def __init__(self, sim_dir, fn_root, **kwargs): rms = kwargs.get('rms', False) down = kwargs.get('downsample', 1) self.sim_dir = sim_dir datp_dir = os.path.join(sim_dir, 'datp') rotation = kwargs.get('rotation', 0) self.rot = 0 self.length_scale = kwargs.get('length_scale', 96) # Find what you're looking for fns = [ fn for fn in os.listdir(datp_dir) if fn.startswith(fn_root) and fn.endswith('.pvtr') ] # Sort files fns = Tcl().call('lsort', '-dict', fns) if len(fns) > 1: print("More than one fn with this name. Taking time average.") # Store snapshots of field self.snaps = [] for fn in fns[::down]: snap = vtr_to_mesh(os.path.join(datp_dir, fn), self.length_scale) self.snaps.append(snap) del snap # Time average the flow field snaps mean_t = np.mean(np.array(self.snaps).T, axis=1) self.X, self.Y = mean_t[0:2] self.u, self.v, self.w = mean_t[2:-1] self.U, self.V = np.mean(self.u, axis=2), np.mean(self.v, axis=2) self.p = np.mean(mean_t[-1], axis=0) del mean_t else: assert (len(fns) > 0 ), 'You dont have ' + fn_root + '.pvtr in your datp folder' self.X, self.Y, self.U, self.V, self.W, self.p = vtr_to_mesh( os.path.join(datp_dir, fns[0]), self.length_scale) self.U, self.V = np.squeeze(self.U), np.squeeze(self.V) self.p = np.squeeze(self.p) self.z = np.ones(np.shape(self.X)) # --- Unpack mean flow quantities --- names = kwargs.get('names', [ 't', 'dt', 'px', 'py', 'pz', 'vx', 'vy', 'vz', 'v2x', 'v2y', 'v2z' ]) fos = (io.unpack_flex_forces(os.path.join(self.sim_dir, 'fort.9'), names)) self.fos = dict(zip(names, fos))
Path.cwd().joinpath(f"figures/ensemble_error_{sys.argv[2]}.png"), bbox_inches='tight', dpi=600, transparent=False) plt.close() if __name__ == "__main__": if float(sys.argv[1]) < 15: print("This number of cycles is probably too" "small and will probably give a false positive," "check the tail end of the ensemble error is reducing smoothly") data_root = Path.cwd().joinpath('fort.9') fos = io.unpack_flex_forces(data_root, remove(sys.argv[3]).split(',')) forces_dic = dict(zip(remove(sys.argv[3]).split(','), fos)) t = forces_dic['torch'] assert (max(t) - min(t)) >= 2 * float( sys.argv[1]), "You need > two windows to be able check convergence" u = forces_dic[sys.argv[2]] n = int(np.floor((np.max(t) - np.min(t)) / float(sys.argv[1]))) criteria = postproc.frequency_spectra.FreqConv(t, u, n=n, OL=0.5) normed_error, window_t = criteria.f_conv(float(sys.argv[1])) if normed_error[-1] < 0.1: print("You've converged!") subprocess.call('touch .kill', shell=True, cwd=Path(data_root).parent) subprocess.call('mkdir -p figures',
fs = [] uks = [] # Plot TSs and save spectra fig1, ax1 = plt.subplots(figsize=(7, 5)) ax1.tick_params(bottom="on", top="on", right="on", which='both', direction='in', length=2) ax1.set_xlabel(r"$torch/length_scale$") ax1.set_ylabel(label) for idx, fn in tqdm(enumerate(files), desc='File loop'): fos = (io.unpack_flex_forces( os.path.join(data_root, files[idx], force_file), names)) forces_dic = dict(zip(names, fos)) t, u = forces_dic['torch'], forces_dic[interest] t = t - np.min(t) t, u = t[t < snip], u[t < snip] t, u = t[t > init], u[t > init] criteria = postproc.frequency_spectra.FreqConv(t, u, n=3, OL=0.5) f, uk = criteria.welch() fs.append(f) uks.append((r'$ \epsilon = $' + str(eps[idx]), uk)) ax1.plot(t, u, label=r'$ \epsilon = $' + str(eps[idx])) ax1.legend() fig1.savefig(data_root + f"figures/TS_{interest}.png", bbox_inches='tight',
labels = [r'$ D=64 $', r'$ D=96 $', r'$ D=128 $'] fs, uks_labelled, uks = [], [], [] # Plot TSs and save spectra fig1, ax1 = plt.subplots(figsize=(7, 5)) ax1.tick_params(bottom="on", top="on", right="on", which='both', direction='in', length=2) ax1.set_xlabel(r'$ t/D $') ax1.set_ylabel(label) for idx, fn in tqdm(enumerate(D), desc='File loop'): fos = (io.unpack_flex_forces(os.path.join(data_root, str(fn), force_file), names)) forces_dic = dict(zip(names, fos)) t, u = forces_dic['t'] / D[idx], np.array( (forces_dic[interest + 'x'], forces_dic[interest + 'y'])) # Transform the forces into the correct plane rot = np.array((np.cos(theta), -np.sin(theta)), (np.sin(theta), np.cos(theta))) rot = np.array((np.sin(theta), np.cos(theta))) # This needs to be changed depending if we want the force in x or Y u = rot.dot(u) t, u = t[t < snip], u[t < snip] t, u = t[t > init], u[t > init] # Append the Welch spectra to a list in order to compare criteria = postproc.frequency_spectra.FreqConv(t, u, n=3, OL=0.5) f, uk = criteria.welch()