Skip to main content

runmat_meshing_size/
refinement.rs

1use std::collections::BTreeMap;
2use std::fmt;
3
4use serde::de::{self, Visitor};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub enum RefinementStrategy {
10    None,
11    Uniform,
12    Adaptive,
13    Auto,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
17#[serde(rename_all = "snake_case")]
18pub enum RefinementFocusLevel {
19    Off,
20    Normal,
21    Fine,
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
25#[serde(rename_all = "snake_case")]
26pub enum RefinementIndicatorMode {
27    Auto,
28    On,
29    Off,
30}
31
32impl<'de> Deserialize<'de> for RefinementIndicatorMode {
33    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
34    where
35        D: serde::Deserializer<'de>,
36    {
37        struct ModeVisitor;
38
39        impl Visitor<'_> for ModeVisitor {
40            type Value = RefinementIndicatorMode;
41
42            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
43                formatter.write_str("auto, on, off, true, or false")
44            }
45
46            fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
47            where
48                E: de::Error,
49            {
50                Ok(if value {
51                    RefinementIndicatorMode::On
52                } else {
53                    RefinementIndicatorMode::Off
54                })
55            }
56
57            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
58            where
59                E: de::Error,
60            {
61                match value.trim().to_ascii_lowercase().as_str() {
62                    "auto" => Ok(RefinementIndicatorMode::Auto),
63                    "on" | "true" => Ok(RefinementIndicatorMode::On),
64                    "off" | "false" => Ok(RefinementIndicatorMode::Off),
65                    other => Err(E::custom(format!(
66                        "invalid refinement indicator mode `{other}`, expected auto, on, or off"
67                    ))),
68                }
69            }
70
71            fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
72            where
73                E: de::Error,
74            {
75                self.visit_str(&value)
76            }
77        }
78
79        deserializer.deserialize_any(ModeVisitor)
80    }
81}
82
83#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
84pub struct RefinementIndicatorOverrides {
85    #[serde(default, flatten)]
86    pub namespaces: BTreeMap<String, BTreeMap<String, RefinementIndicatorMode>>,
87}
88
89#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
90pub struct RefinementFocusOptions {
91    pub loads: RefinementFocusLevel,
92    pub constraints: RefinementFocusLevel,
93    pub interfaces: RefinementFocusLevel,
94    pub curvature: bool,
95    pub small_features: bool,
96}
97
98impl Default for RefinementFocusOptions {
99    fn default() -> Self {
100        Self {
101            loads: RefinementFocusLevel::Fine,
102            constraints: RefinementFocusLevel::Fine,
103            interfaces: RefinementFocusLevel::Normal,
104            curvature: true,
105            small_features: true,
106        }
107    }
108}
109
110#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
111pub struct RefinementConvergenceOptions {
112    pub field_change_tolerance: f64,
113    pub energy_change_tolerance: f64,
114    #[serde(default)]
115    pub residual_tolerance: Option<f64>,
116}
117
118impl Default for RefinementConvergenceOptions {
119    fn default() -> Self {
120        Self {
121            field_change_tolerance: 0.05,
122            energy_change_tolerance: 0.02,
123            residual_tolerance: None,
124        }
125    }
126}
127
128#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
129pub struct MeshRefinementOptions {
130    pub strategy: RefinementStrategy,
131    pub max_iterations: usize,
132    pub convergence: RefinementConvergenceOptions,
133    pub focus: RefinementFocusOptions,
134    #[serde(default)]
135    pub indicators: RefinementIndicatorOverrides,
136}
137
138impl Default for MeshRefinementOptions {
139    fn default() -> Self {
140        Self {
141            strategy: RefinementStrategy::Auto,
142            max_iterations: 4,
143            convergence: RefinementConvergenceOptions::default(),
144            focus: RefinementFocusOptions::default(),
145            indicators: RefinementIndicatorOverrides::default(),
146        }
147    }
148}
149
150pub type AdaptiveMeshingOptions = MeshRefinementOptions;