1use super::*;
2
3pub struct ReliabilityAnalyzer {
5 reliability_methods: ReliabilityMethods,
6 failure_analysis: FailureAnalysis,
7 maintenance_optimization: MaintenanceOptimization,
8 statistical_computing: Option<Arc<Mutex<StatisticalComputingLibrary>>>,
10}
11
12pub struct ReliabilityMethods {
14 probability_analysis: ProbabilityAnalysis,
15 statistical_analysis: StatisticalAnalysis,
16 monte_carlo: MonteCarlo,
17}
18
19#[derive(Debug, Clone)]
21pub struct ProbabilityAnalysis {
22 pub probability_distribution: ProbabilityDistribution,
23 pub reliability_function: ReliabilityFunction,
24}
25
26#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
28pub enum ProbabilityDistribution {
29 Normal,
30 LogNormal,
31 Exponential,
32 Weibull,
33 Custom(String),
34}
35
36#[derive(Debug, Clone)]
38pub struct ReliabilityFunction {
39 pub function_type: ReliabilityFunctionType,
40 pub parameters: Vec<f64>,
41}
42
43#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
45pub enum ReliabilityFunctionType {
46 Exponential,
47 Weibull,
48 LogNormal,
49 Custom(String),
50}
51
52#[derive(Debug, Clone)]
54pub struct StatisticalAnalysis {
55 pub confidence_interval: ConfidenceInterval,
56 pub hypothesis_testing: HypothesisTesting,
57}
58
59#[derive(Debug, Clone)]
61pub struct ConfidenceInterval {
62 pub confidence_level: f64,
63 pub lower_bound: f64,
64 pub upper_bound: f64,
65}
66
67#[derive(Debug, Clone)]
69pub struct HypothesisTesting {
70 pub null_hypothesis: String,
71 pub alternative_hypothesis: String,
72 pub test_statistic: f64,
73 pub p_value: f64,
74}
75
76#[derive(Debug, Clone)]
78pub struct MonteCarlo {
79 pub num_simulations: u32,
80 pub random_variables: Vec<RandomVariable>,
81 pub simulation_results: Vec<f64>,
82}
83
84#[derive(Debug, Clone)]
86pub struct RandomVariable {
87 pub variable_name: String,
88 pub distribution: ProbabilityDistribution,
89 pub parameters: Vec<f64>,
90}
91
92pub struct FailureAnalysis {
94 failure_modes: FailureModes,
95 fault_tree: FaultTree,
96 fmea: FMEA,
97}
98
99#[derive(Debug, Clone)]
101pub struct FailureModes {
102 pub failure_mode_id: String,
103 pub failure_mode_name: String,
104 pub failure_causes: Vec<FailureCause>,
105 pub failure_effects: Vec<FailureEffect>,
106}
107
108#[derive(Debug, Clone)]
110pub struct FailureCause {
111 pub cause_id: String,
112 pub cause_description: String,
113 pub cause_probability: f64,
114}
115
116#[derive(Debug, Clone)]
118pub struct FailureEffect {
119 pub effect_id: String,
120 pub effect_description: String,
121 pub effect_severity: EffectSeverity,
122}
123
124#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
126pub enum EffectSeverity {
127 Minor,
128 Major,
129 Critical,
130 Catastrophic,
131}
132
133#[derive(Debug, Clone)]
135pub struct FaultTree {
136 pub tree_id: String,
137 pub top_event: String,
138 pub logic_gates: Vec<LogicGate>,
139 pub basic_events: Vec<BasicEvent>,
140}
141
142#[derive(Debug, Clone)]
144pub struct LogicGate {
145 pub gate_id: String,
146 pub gate_type: LogicGateType,
147 pub inputs: Vec<String>,
148}
149
150#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
152pub enum LogicGateType {
153 AND,
154 OR,
155 NOT,
156 NAND,
157 NOR,
158 XOR,
159}
160
161#[derive(Debug, Clone)]
163pub struct BasicEvent {
164 pub event_id: String,
165 pub event_description: String,
166 pub event_probability: f64,
167}
168
169#[derive(Debug, Clone)]
171pub struct FMEA {
172 pub fmea_id: String,
173 pub failure_modes: Vec<FMEAItem>,
174}
175
176#[derive(Debug, Clone)]
178pub struct FMEAItem {
179 pub item_id: String,
180 pub component: String,
181 pub failure_mode: String,
182 pub failure_cause: String,
183 pub failure_effect: String,
184 pub severity: u32,
185 pub occurrence: u32,
186 pub detection: u32,
187 pub rpn: u32,
188}
189
190pub struct MaintenanceOptimization {
192 preventive_maintenance: PreventiveMaintenance,
193 predictive_maintenance: PredictiveMaintenance,
194 condition_based_maintenance: ConditionBasedMaintenance,
195}
196
197#[derive(Debug, Clone)]
199pub struct PreventiveMaintenance {
200 pub maintenance_interval: u32,
201 pub maintenance_tasks: Vec<MaintenanceTask>,
202}
203
204#[derive(Debug, Clone)]
206pub struct MaintenanceTask {
207 pub task_id: String,
208 pub task_name: String,
209 pub task_duration: f64,
210 pub task_cost: f64,
211}
212
213#[derive(Debug, Clone)]
215pub struct PredictiveMaintenance {
216 pub prediction_model: PredictionModel,
217 pub prediction_horizon: u32,
218}
219
220#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
222pub enum PredictionModel {
223 Weibull,
224 Exponential,
225 NeuralNetwork,
226 Custom(String),
227}
228
229#[derive(Debug, Clone)]
231pub struct ConditionBasedMaintenance {
232 pub monitoring_parameters: Vec<MonitoringParameter>,
233 pub threshold_values: Vec<f64>,
234}
235
236#[derive(Debug, Clone)]
238pub struct MonitoringParameter {
239 pub parameter_name: String,
240 pub measurement_method: MeasurementMethod,
241}
242
243#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
245pub enum MeasurementMethod {
246 Vibration,
247 Temperature,
248 Pressure,
249 OilAnalysis,
250}
251
252#[derive(Debug, Clone)]
254pub struct ReliabilityResults {
255 pub results_id: String,
256 pub reliability_index: f64,
257 pub failure_probability: f64,
258 pub mean_time_to_failure: f64,
259 pub maintenance_interval: u64,
260}
261
262#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
270pub enum SystemModel {
271 Series,
272 Parallel,
273 KOutOfN {
274 k: usize,
276 n: usize,
279 },
280}
281
282#[derive(Debug, Clone, Serialize, Deserialize)]
287pub struct ComponentReliability {
288 pub name: String,
289 pub failure_probability: f64,
290 pub mean_time_to_failure: f64,
291}
292
293impl ComponentReliability {
294 pub fn new(
295 name: impl Into<String>,
296 failure_probability: f64,
297 mean_time_to_failure: f64,
298 ) -> Self {
299 Self {
300 name: name.into(),
301 failure_probability,
302 mean_time_to_failure,
303 }
304 }
305}
306
307#[derive(Debug, Clone, Serialize, Deserialize)]
310pub struct ReliabilityConfig {
311 pub num_simulations: usize,
313 pub components: Vec<ComponentReliability>,
316 pub system_model: SystemModel,
318}
319
320impl Default for ReliabilityConfig {
321 fn default() -> Self {
322 Self {
323 num_simulations: 10_000,
324 components: Vec::new(),
325 system_model: SystemModel::Series,
326 }
327 }
328}
329
330impl ReliabilityConfig {
331 pub fn new(system_model: SystemModel, components: Vec<ComponentReliability>) -> Self {
332 Self {
333 num_simulations: 10_000,
334 components,
335 system_model,
336 }
337 }
338}
339
340#[derive(Debug, Clone)]
342pub struct ReliabilityResult {
343 pub system_reliability: f64,
346 pub mean_availability: f64,
351 pub failure_rate: f64,
353 pub mtbf: f64,
358 pub component_importance: HashMap<String, f64>,
363 pub confidence_interval: (f64, f64),
367}
368impl ReliabilityAnalyzer {
369 pub fn new() -> Self {
370 Self {
371 reliability_methods: ReliabilityMethods::new(),
372 failure_analysis: FailureAnalysis::new(),
373 maintenance_optimization: MaintenanceOptimization::new(),
374 statistical_computing: None,
375 }
376 }
377
378 pub fn attach_statistical_computing(
381 &mut self,
382 lib: Option<Arc<Mutex<StatisticalComputingLibrary>>>,
383 ) {
384 self.statistical_computing = lib;
385 }
386
387 pub fn initialize(&mut self) -> Result<(), EngineeringError> {
388 self.reliability_methods.initialize()?;
389 self.failure_analysis.initialize()?;
390 self.maintenance_optimization.initialize()?;
391 Ok(())
392 }
393
394 pub fn validate_model(&self, model: &EngineeringModel) -> Result<(), EngineeringError> {
395 if model.geometry.dimensions.is_empty() {
396 return Err(EngineeringError::ValidationError(
397 "Model must have dimensions".to_string(),
398 ));
399 }
400 Ok(())
401 }
402
403 pub fn analyze(
404 &mut self,
405 model: &EngineeringModel,
406 _analysis_type: AnalysisType,
407 ) -> Result<ReliabilityResults, EngineeringError> {
408 let material = model.materials.values().next().ok_or_else(|| {
424 EngineeringError::InsufficientData(
425 "model has no material; cannot compute reliability".to_string(),
426 )
427 })?;
428 let mp = &material.material_properties;
429 let yield_strength = mp.yield_strength;
430 let ultimate_strength = mp.ultimate_strength;
431
432 if yield_strength <= 0.0 {
433 return Err(EngineeringError::InsufficientData(
434 "material yield_strength must be positive".to_string(),
435 ));
436 }
437
438 let total_force: f64 = model
440 .loads
441 .iter()
442 .filter(|l| matches!(l.load_type, LoadType::Force))
443 .map(|l| l.load_magnitude)
444 .sum();
445
446 if total_force <= 0.0 {
447 return Err(EngineeringError::InsufficientData(
448 "no axial force loads on the model; cannot compute applied stress".to_string(),
449 ));
450 }
451
452 let area = model
456 .materials
457 .values()
458 .next()
459 .and_then(|_m| {
460 None::<f64>
463 })
464 .unwrap_or_else(|| {
465 let dims = &model.geometry.dimensions;
466 if dims.is_empty() {
467 1.0 } else {
469 dims[0].min(1.0).max(0.001) * dims.get(1).unwrap_or(&1.0).min(1.0).max(0.001)
470 }
471 });
472
473 let applied_stress = total_force / area;
474 let safety_factor = yield_strength / applied_stress;
475
476 let ductility_ratio = (ultimate_strength - yield_strength) / yield_strength;
482 let cov = 0.10 + 0.05 * (1.0 - ductility_ratio.clamp(0.0, 1.0));
483 let sigma_sf = cov * safety_factor;
484
485 let beta = if sigma_sf > 0.0 {
488 (safety_factor - 1.0) / sigma_sf
489 } else {
490 if safety_factor > 1.0 {
491 6.0
492 } else {
493 -6.0
494 } };
496
497 let failure_probability = normal_cdf(-beta);
499
500 let mean_time_to_failure = if failure_probability > 0.0 && failure_probability.is_finite() {
502 1.0 / failure_probability
503 } else {
504 f64::INFINITY
505 };
506
507 let maintenance_interval = ((safety_factor * 30.0) as u64).min(365).max(1);
510
511 Ok(ReliabilityResults {
512 results_id: format!("reliability_{}", model.model_id),
513 reliability_index: beta,
514 failure_probability,
515 mean_time_to_failure,
516 maintenance_interval,
517 })
518 }
519
520 pub fn analyze_monte_carlo(
531 &mut self,
532 limit_state_function: &[f64],
533 mean: f64,
534 std_dev: f64,
535 ) -> Result<ReliabilityResults, EngineeringError> {
536 if limit_state_function.is_empty() {
537 return Err(EngineeringError::InsufficientData(
538 "limit_state_function must contain at least the threshold value".to_string(),
539 ));
540 }
541 if std_dev < 0.0 {
542 return Err(EngineeringError::ValidationError(
543 "std_dev must be non-negative".to_string(),
544 ));
545 }
546 let threshold = limit_state_function[0];
547 let num_sims = self.reliability_methods.monte_carlo.num_simulations as usize;
548 if num_sims == 0 {
549 return Err(EngineeringError::InsufficientData(
550 "num_simulations is zero".to_string(),
551 ));
552 }
553
554 let samples = self
555 .reliability_methods
556 .monte_carlo
557 .run_simulation(mean, std_dev, num_sims);
558
559 let mut failures = 0u64;
560 for &x in &samples {
561 if x - threshold < 0.0 {
563 failures += 1;
564 }
565 }
566
567 let failure_probability = failures as f64 / num_sims as f64;
568 let reliability_index = self.compute_reliability_index(failure_probability);
569
570 let mean_time_to_failure = if failure_probability > 0.0 {
574 1.0 / failure_probability
575 } else {
576 f64::INFINITY
577 };
578
579 Ok(ReliabilityResults {
580 results_id: "monte_carlo".to_string(),
581 reliability_index,
582 failure_probability,
583 mean_time_to_failure,
584 maintenance_interval: 30,
585 })
586 }
587
588 pub fn compute_reliability_index(&self, failure_prob: f64) -> f64 {
592 -inverse_normal_cdf(failure_prob)
593 }
594
595 pub fn analyze_reliability(
619 &self,
620 config: &ReliabilityConfig,
621 ) -> Result<ReliabilityResult, EngineeringError> {
622 if config.components.is_empty() {
624 return Err(EngineeringError::InsufficientData(
625 "at least one component is required".to_string(),
626 ));
627 }
628 if config.num_simulations == 0 {
629 return Err(EngineeringError::InsufficientData(
630 "num_simulations must be greater than zero".to_string(),
631 ));
632 }
633 for c in &config.components {
634 if !(0.0..=1.0).contains(&c.failure_probability) {
635 return Err(EngineeringError::ValidationError(format!(
636 "component '{}' failure_probability must be in [0, 1], got {}",
637 c.name, c.failure_probability
638 )));
639 }
640 if c.mean_time_to_failure < 0.0 {
641 return Err(EngineeringError::ValidationError(format!(
642 "component '{}' mean_time_to_failure must be non-negative, got {}",
643 c.name, c.mean_time_to_failure
644 )));
645 }
646 }
647 let n = config.components.len();
648 if let SystemModel::KOutOfN { k, n: kn } = &config.system_model {
649 if *kn != n {
650 return Err(EngineeringError::ValidationError(format!(
651 "KOutOfN.n ({}) must equal the number of components ({})",
652 kn, n
653 )));
654 }
655 if *k == 0 || *k > n {
656 return Err(EngineeringError::ValidationError(format!(
657 "KOutOfN.k ({}) must satisfy 1 <= k <= n ({})",
658 k, n
659 )));
660 }
661 }
662
663 let num_sims = config.num_simulations;
665 let mut working_runs: u64 = 0;
666 for _ in 0..num_sims {
667 let states: Vec<bool> = config
671 .components
672 .iter()
673 .map(|c| rand::random::<f64>() >= c.failure_probability)
674 .collect();
675 if system_works(&states, &config.system_model) {
676 working_runs += 1;
677 }
678 }
679
680 let system_reliability = working_runs as f64 / num_sims as f64;
681 let failure_rate = 1.0 - system_reliability;
682
683 let avg_mttf: f64 = {
688 let sum: f64 = config
689 .components
690 .iter()
691 .map(|c| c.mean_time_to_failure)
692 .sum();
693 sum / n as f64
694 };
695 let time_scale = if avg_mttf > 0.0 { avg_mttf } else { 1.0 };
696 let mtbf = if failure_rate > 0.0 {
697 (1.0 / failure_rate) * time_scale
698 } else {
699 f64::INFINITY
700 };
701
702 let mean_availability = system_reliability;
706
707 let nominal_r: Vec<f64> = config
709 .components
710 .iter()
711 .map(|c| 1.0 - c.failure_probability)
712 .collect();
713 let mut component_importance = HashMap::with_capacity(n);
714 for i in 0..n {
715 let mut r_up = nominal_r.clone();
716 r_up[i] = 1.0;
717 let mut r_down = nominal_r.clone();
718 r_down[i] = 0.0;
719 let sys_up =
720 system_reliability_from_component_reliabilities(&r_up, &config.system_model);
721 let sys_down =
722 system_reliability_from_component_reliabilities(&r_down, &config.system_model);
723 component_importance.insert(config.components[i].name.clone(), sys_up - sys_down);
725 }
726
727 let p = system_reliability;
729 let se = (p * (1.0 - p) / num_sims as f64).sqrt();
730 let z = 1.96;
731 let mut lower = p - z * se;
732 let mut upper = p + z * se;
733 if lower < 0.0 {
734 lower = 0.0;
735 }
736 if upper > 1.0 {
737 upper = 1.0;
738 }
739
740 Ok(ReliabilityResult {
741 system_reliability,
742 mean_availability,
743 failure_rate,
744 mtbf,
745 component_importance,
746 confidence_interval: (lower, upper),
747 })
748 }
749}
750
751fn system_works(states: &[bool], model: &SystemModel) -> bool {
761 match model {
762 SystemModel::Series => states.iter().all(|&w| w),
763 SystemModel::Parallel => states.iter().any(|&w| w),
764 SystemModel::KOutOfN { k, .. } => states.iter().filter(|&&w| w).count() >= *k,
765 }
766}
767
768fn system_reliability_from_component_reliabilities(r: &[f64], model: &SystemModel) -> f64 {
776 match model {
777 SystemModel::Series => r.iter().product(),
778 SystemModel::Parallel => 1.0 - r.iter().map(|&ri| 1.0 - ri).product::<f64>(),
779 SystemModel::KOutOfN { k, .. } => {
780 let mut prob = vec![0.0; r.len() + 1];
782 prob[0] = 1.0;
783 for &ri in r {
784 for j in (0..=r.len()).rev() {
786 prob[j] = prob[j] * (1.0 - ri) + if j > 0 { prob[j - 1] * ri } else { 0.0 };
787 }
788 }
789 prob[*k..].iter().sum()
791 }
792 }
793}
794
795impl ReliabilityMethods {
796 pub fn new() -> Self {
797 Self {
798 probability_analysis: ProbabilityAnalysis::new(),
799 statistical_analysis: StatisticalAnalysis::new(),
800 monte_carlo: MonteCarlo::new(),
801 }
802 }
803
804 pub fn initialize(&mut self) -> Result<(), EngineeringError> {
805 Ok(())
806 }
807
808 pub fn probability_analysis(&self) -> &ProbabilityAnalysis {
810 &self.probability_analysis
811 }
812
813 pub fn probability_analysis_mut(&mut self) -> &mut ProbabilityAnalysis {
815 &mut self.probability_analysis
816 }
817
818 pub fn statistical_analysis(&self) -> &StatisticalAnalysis {
820 &self.statistical_analysis
821 }
822
823 pub fn statistical_analysis_mut(&mut self) -> &mut StatisticalAnalysis {
825 &mut self.statistical_analysis
826 }
827}
828
829impl ProbabilityAnalysis {
830 pub fn new() -> Self {
831 Self {
832 probability_distribution: ProbabilityDistribution::Weibull,
833 reliability_function: ReliabilityFunction::new(),
834 }
835 }
836}
837
838impl ReliabilityFunction {
839 pub fn new() -> Self {
840 Self {
841 function_type: ReliabilityFunctionType::Weibull,
842 parameters: vec![2.0, 1000.0],
843 }
844 }
845}
846
847impl StatisticalAnalysis {
848 pub fn new() -> Self {
849 Self {
850 confidence_interval: ConfidenceInterval::new(),
851 hypothesis_testing: HypothesisTesting::new(),
852 }
853 }
854}
855
856impl ConfidenceInterval {
857 pub fn new() -> Self {
858 Self {
859 confidence_level: 0.95,
860 lower_bound: 0.0,
861 upper_bound: 1.0,
862 }
863 }
864}
865
866impl HypothesisTesting {
867 pub fn new() -> Self {
868 Self {
869 null_hypothesis: "No failure".to_string(),
870 alternative_hypothesis: "Failure occurs".to_string(),
871 test_statistic: 1.96,
872 p_value: 0.05,
873 }
874 }
875}
876
877impl MonteCarlo {
878 pub fn new() -> Self {
879 Self {
880 num_simulations: 10000,
881 random_variables: Vec::new(),
882 simulation_results: Vec::new(),
883 }
884 }
885
886 pub fn run_simulation(&mut self, mean: f64, std_dev: f64, num_sims: usize) -> Vec<f64> {
890 let mut samples = Vec::with_capacity(num_sims);
891 for _ in 0..num_sims {
892 let z = standard_normal_sample();
893 samples.push(mean + std_dev * z);
894 }
895 self.simulation_results = samples.clone();
896 self.num_simulations = num_sims as u32;
897 samples
898 }
899}
900
901impl RandomVariable {
902 pub fn new() -> Self {
903 Self {
904 variable_name: "load".to_string(),
905 distribution: ProbabilityDistribution::Normal,
906 parameters: vec![100.0, 10.0],
907 }
908 }
909}
910
911impl FailureAnalysis {
912 pub fn new() -> Self {
913 Self {
914 failure_modes: FailureModes::new(),
915 fault_tree: FaultTree::new(),
916 fmea: FMEA::new(),
917 }
918 }
919
920 pub fn initialize(&mut self) -> Result<(), EngineeringError> {
921 Ok(())
922 }
923
924 pub fn failure_modes(&self) -> &FailureModes {
926 &self.failure_modes
927 }
928
929 pub fn failure_modes_mut(&mut self) -> &mut FailureModes {
931 &mut self.failure_modes
932 }
933
934 pub fn fault_tree(&self) -> &FaultTree {
936 &self.fault_tree
937 }
938
939 pub fn fault_tree_mut(&mut self) -> &mut FaultTree {
941 &mut self.fault_tree
942 }
943
944 pub fn fmea(&self) -> &FMEA {
946 &self.fmea
947 }
948
949 pub fn fmea_mut(&mut self) -> &mut FMEA {
951 &mut self.fmea
952 }
953}
954
955impl FailureModes {
956 pub fn new() -> Self {
957 Self {
958 failure_mode_id: "fm_1".to_string(),
959 failure_mode_name: "Fracture".to_string(),
960 failure_causes: Vec::new(),
961 failure_effects: Vec::new(),
962 }
963 }
964}
965
966impl FaultTree {
967 pub fn new() -> Self {
968 Self {
969 tree_id: "ft_1".to_string(),
970 top_event: "System Failure".to_string(),
971 logic_gates: Vec::new(),
972 basic_events: Vec::new(),
973 }
974 }
975}
976
977impl FMEA {
978 pub fn new() -> Self {
979 Self {
980 fmea_id: "fmea_1".to_string(),
981 failure_modes: Vec::new(),
982 }
983 }
984}
985
986impl MaintenanceOptimization {
987 pub fn new() -> Self {
988 Self {
989 preventive_maintenance: PreventiveMaintenance::new(),
990 predictive_maintenance: PredictiveMaintenance::new(),
991 condition_based_maintenance: ConditionBasedMaintenance::new(),
992 }
993 }
994
995 pub fn initialize(&mut self) -> Result<(), EngineeringError> {
996 Ok(())
997 }
998
999 pub fn preventive_maintenance(&self) -> &PreventiveMaintenance {
1001 &self.preventive_maintenance
1002 }
1003
1004 pub fn preventive_maintenance_mut(&mut self) -> &mut PreventiveMaintenance {
1006 &mut self.preventive_maintenance
1007 }
1008
1009 pub fn predictive_maintenance(&self) -> &PredictiveMaintenance {
1011 &self.predictive_maintenance
1012 }
1013
1014 pub fn predictive_maintenance_mut(&mut self) -> &mut PredictiveMaintenance {
1016 &mut self.predictive_maintenance
1017 }
1018
1019 pub fn condition_based_maintenance(&self) -> &ConditionBasedMaintenance {
1021 &self.condition_based_maintenance
1022 }
1023
1024 pub fn condition_based_maintenance_mut(&mut self) -> &mut ConditionBasedMaintenance {
1026 &mut self.condition_based_maintenance
1027 }
1028}
1029
1030impl PreventiveMaintenance {
1031 pub fn new() -> Self {
1032 Self {
1033 maintenance_interval: 30,
1034 maintenance_tasks: Vec::new(),
1035 }
1036 }
1037}
1038
1039impl MaintenanceTask {
1040 pub fn new() -> Self {
1041 Self {
1042 task_id: "task_1".to_string(),
1043 task_name: "Inspection".to_string(),
1044 task_duration: 2.0,
1045 task_cost: 100.0,
1046 }
1047 }
1048}
1049
1050impl PredictiveMaintenance {
1051 pub fn new() -> Self {
1052 Self {
1053 prediction_model: PredictionModel::Weibull,
1054 prediction_horizon: 90,
1055 }
1056 }
1057}
1058
1059impl ConditionBasedMaintenance {
1060 pub fn new() -> Self {
1061 Self {
1062 monitoring_parameters: Vec::new(),
1063 threshold_values: Vec::new(),
1064 }
1065 }
1066}
1067
1068impl MonitoringParameter {
1069 pub fn new() -> Self {
1070 Self {
1071 parameter_name: "vibration".to_string(),
1072 measurement_method: MeasurementMethod::Vibration,
1073 }
1074 }
1075}