1use crate::traits::Mesh;
3#[cfg(feature = "mpi")]
4use crate::traits::ParallelMesh;
5#[cfg(feature = "mpi")]
6use mpi::traits::Communicator;
7use std::fs;
8
9pub trait ConvertToSerializable {
10 type SerializableType: serde::Serialize;
12 fn to_serializable(&self) -> Self::SerializableType;
14 fn from_serializable(ron: Self::SerializableType) -> Self;
16}
17
18pub trait RONExport: Mesh {
19 fn to_ron_string(&self) -> String;
23
24 fn export_as_ron(&self, filename: &str) {
26 let ron_s = self.to_ron_string();
27 fs::write(filename, ron_s).expect("Unable to write file");
28 }
29}
30
31pub trait RONImport: Sized + Mesh {
32 fn from_ron_string(s: String) -> Self;
36
37 fn import_from_ron(filename: &str) -> Self {
39 let content = fs::read_to_string(filename).expect("Unable to read file");
40 Self::from_ron_string(content)
41 }
42}
43
44#[cfg(feature = "mpi")]
45#[derive(Debug, serde::Serialize, serde::Deserialize)]
46pub struct ParallelMeshSummaryData {
48 mpi_ranks: i32,
49}
50
51#[cfg(feature = "mpi")]
52pub trait RONExportParallel<'a, C: Communicator + 'a>: ParallelMesh<C = C>
53where
54 Self::LocalMesh: RONExport,
55 Self: 'a,
56{
57 fn export_as_ron(&'a self, filename: &str) {
61 let parts = filename.split('.').collect::<Vec<_>>();
62 assert!(parts.len() > 1);
63 let sub_filename = format!(
64 "{}.{}.{}",
65 parts[0..parts.len() - 1].join("."),
66 self.comm().rank(),
67 parts[parts.len() - 1]
68 );
69
70 self.local_mesh().export_as_ron(&sub_filename);
71 if self.comm().rank() == 0 {
72 let mesh_data = ParallelMeshSummaryData {
73 mpi_ranks: self.comm().size(),
74 };
75 fs::write(filename, ron::to_string(&mesh_data).unwrap()).expect("Unable to write file");
76 }
77 }
78}
79
80#[cfg(feature = "mpi")]
81pub trait RONImportParallel<'a, C: Communicator + 'a>: Sized + ParallelMesh<C = C>
82where
83 Self::LocalMesh: RONImport,
84 Self: 'a,
85{
86 fn create_from_ron_info(comm: &'a C, local_mesh: Self::LocalMesh) -> Self;
90
91 fn import_from_ron(comm: &'a C, filename: &str) -> Self {
93 let parts = filename.split('.').collect::<Vec<_>>();
94 assert!(parts.len() > 1);
95 let sub_filename = format!(
96 "{}.{}.{}",
97 parts[0..parts.len() - 1].join("."),
98 comm.rank(),
99 parts[parts.len() - 1]
100 );
101
102 let content = fs::read_to_string(filename).expect("Unable to read file");
103 let summary: ParallelMeshSummaryData = ron::from_str(&content).unwrap();
104
105 if summary.mpi_ranks != comm.size() {
106 panic!("Incorrect number of MPI ranks");
107 }
108
109 let local_mesh = Self::LocalMesh::import_from_ron(&sub_filename);
110 Self::create_from_ron_info(comm, local_mesh)
111 }
112}