16 def __init__(self, folder="./output", csv_dict=None, cell_fields=None):
17 """
18 Parameters
19 ----------
20 folder : str
21 Relative path to folder containing the CSV files.
22 csv_dict : dict
23 Dictionary mapping attribute names -> CSV filenames.
24 Special keys:
25 - "x": spatial node positions (single column)
26 - "time": time array (single column)
27 - "dx": cell sizes (single column)
28 cell_fields : list
29 List of names that are defined on cells (not nodes).
30 """
31 self.colormap = plt.cm.viridis
32 plt.rcParams.update({'font.size':15,'lines.linewidth':2.5,'figure.autolayout':True})
33
34 self.folder = folder
35 if csv_dict is None:
36 raise ValueError("You must provide a csv_dict mapping names to CSV files.")
37 if cell_fields is None:
38 cell_fields = []
39
40 self._names = list(csv_dict.keys())
41 self._cell_fields = cell_fields
42
43
44 self.x = None
45 self.time = None
46 self.dx = None
47 self.x_cell = None
48
49
50 for name, fname in csv_dict.items():
51 path = os.path.join(folder, fname)
52 if not os.path.exists(path):
53 raise FileNotFoundError(f"CSV file not found: {path}")
54 print(f"[PostProcessor] Loading {name} from {path}")
55 data = np.loadtxt(path, skiprows=1)
56
57
58 if name in ("x", "time", "dx"):
59 data = data.flatten()
60 setattr(self, name, data)
61 else:
62 setattr(self, name, data)
63
64
65 first_field = next((n for n in self._names if n not in ("x", "time", "dx")), None)
66 if first_field is None:
67 raise ValueError("No field CSVs found (excluding 'x', 'time', 'dx').")
68
69 data_field = getattr(self, first_field)
70
71 if self.x is None:
72 self.x = np.arange(data_field.shape[1])
73 if self.time is None:
74 self.time = np.arange(data_field.shape[0])
75
76
77 if hasattr(self, "dx") and self.dx is not None:
78 if len(self.dx) != len(self.x)-1:
79 raise ValueError("dx length must be number of nodes - 1")
80 self.x_cell = self.x[:-1] + 0.5*self.dx
81