1use crate::traits::Grid;
3#[cfg(feature = "mpi")]
4use crate::traits::ParallelGrid;
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: Grid {
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 + Grid {
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 ParallelGridSummaryData {
48 mpi_ranks: i32,
49}
50
51#[cfg(feature = "mpi")]
52pub trait RONExportParallel<'a, C: Communicator + 'a>: ParallelGrid<C = C>
53where
54 Self::LocalGrid: 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_grid().export_as_ron(&sub_filename);
71 if self.comm().rank() == 0 {
72 let grid_data = ParallelGridSummaryData {
73 mpi_ranks: self.comm().size(),
74 };
75 fs::write(filename, ron::to_string(&grid_data).unwrap()).expect("Unable to write file");
76 }
77 }
78}
79
80#[cfg(feature = "mpi")]
81pub trait RONImportParallel<'a, C: Communicator + 'a>: Sized + ParallelGrid<C = C>
82where
83 Self::LocalGrid: RONImport,
84 Self: 'a,
85{
86 fn create_from_ron_info(comm: &'a C, local_grid: Self::LocalGrid) -> 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: ParallelGridSummaryData = 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_grid = Self::LocalGrid::import_from_ron(&sub_filename);
110 Self::create_from_ron_info(comm, local_grid)
111 }
112}