def test_get_time_averaged_values(self): """Test function `get_time_averaged_values`.""" dim = 3 # Load forces from file. filepath1 = self.datadir / f'forces{dim}d-single-0.txt' filepath2 = self.datadir / f'forces{dim}d-single-5.txt' t, fx, fy, fz = petibmpy.read_forces(filepath1, filepath2) # Compute time-averaged value in one direction. fx1, = petibmpy.get_time_averaged_values(t, fx) self.assertAlmostEqual(fx1, numpy.mean(fx), places=7) # Compute time-averaged value for each direction. fx1, fy1, fz1 = petibmpy.get_time_averaged_values(t, fx, fy, fz) self.assertAlmostEqual(fx1, numpy.mean(fx), places=7) self.assertAlmostEqual(fy1, numpy.mean(fy), places=7) self.assertAlmostEqual(fz1, numpy.mean(fz), places=7) # Compute averaged values providing larger time interval. time_limits = (-1.0, 100.0) fx1, fy1, fz1 = petibmpy.get_time_averaged_values(t, fx, fy, fz, limits=time_limits) self.assertAlmostEqual(fx1, numpy.mean(fx), places=7) self.assertAlmostEqual(fy1, numpy.mean(fy), places=7) self.assertAlmostEqual(fz1, numpy.mean(fz), places=7) # Compute averaged values providing restricted time interval. time_limits = (5.0, 6.0) fx1, fy1, fz1 = petibmpy.get_time_averaged_values(t, fx, fy, fz, limits=time_limits) self.assertAlmostEqual(fx1, 0.55) self.assertAlmostEqual(fy1, 1.55) self.assertAlmostEqual(fz1, 2.55) # Check if runtime error is raised when wrong time limits are set. time_limits = (5.5, 5.5) # 5.5 is not a saved time value with self.assertRaises(RuntimeError): fx1, = petibmpy.get_time_averaged_values(t, fx, limits=time_limits)
def get_stats(solution, limits=(0, numpy.infty)): """Compute mean and rms values of the force coefficients.""" means = Stats(*petibmpy.get_time_averaged_values(*solution, limits=limits)) rms = Stats(*petibmpy.get_rms_values(*solution, limits=limits)) return means, rms
rho = 1.0 U_inf = 1.0 R = 0.5 A = numpy.pi * R**2 coeff = 1 / (0.5 * rho * U_inf**2 * A) # Load forces from file and compute force coefficients. filepath = datadir / 'forces-0.txt' t, fx, fy, fz = petibmpy.read_forces(filepath) cd, cl, cz = petibmpy.get_force_coefficients(fx, fy, fz, coeff=coeff) clz = numpy.sqrt(cl**2 + cz**2) # Compute the time-averaged force coefficients. time_limits = (200.0, 250.0) cd_mean, clz_mean = petibmpy.get_time_averaged_values(t, cd, clz, limits=time_limits) print('Time-averaged force coefficients:\n') print(f'* <CD> = {cd_mean:0.4f}') print(f'* <sqrt(CL^2 + CZ^2)> = {clz_mean:0.4f}') print(f'\n(Time limits: {time_limits})') # Plot history of the force coefficients. pyplot.rc('font', family='serif', size=14) fig, ax = pyplot.subplots(figsize=(6.0, 4.0)) ax.set_xlabel('Non-dimensional time') ax.set_ylabel('Force coefficients') ax.plot(t, cd, label='$C_D$') ax.plot(t, clz, label='$\sqrt{C_L^2 + C_z^2}$') ax.legend(frameon=False) ax.set_xlim(200.0, 250.0)
import petibmpy simudir = pathlib.Path(__file__).absolute().parents[1] # Read 3D forces and convert to force coefficients. filepath = simudir / 'output' / 'forces-0.txt' t, fx, fy, fz = petibmpy.read_forces(filepath) rho, u_inf = 1.0, 1.0 # density and freestream speed dyn_pressure = 0.5 * rho * u_inf**2 # dynamic pressure c = 1.0 # chord length Lz = 3.2 * c # spanwise length coeff = 1 / (dyn_pressure * c * Lz) # scaling factor for force coefficients cd, cl, cz = petibmpy.get_force_coefficients(fx, fy, fz, coeff=coeff) cd_avg, cl_avg = petibmpy.get_time_averaged_values(t, cd, cl, limits=(40.0, 80.0)) # Read 2D forces and convert to force coefficients. rootdir = simudir.parent simudir2d = rootdir / 'snake2d2k35' filepath = simudir2d / 'output' / 'forces-0.txt' t2, fx2, fy2 = petibmpy.read_forces(filepath) coeff = 1 / (dyn_pressure * c) cd2, cl2 = petibmpy.get_force_coefficients(fx2, fy2, coeff=coeff) cd2_avg, cl2_avg = petibmpy.get_time_averaged_values(t2, cd2, cl2, limits=(40.0, 80.0)) cd_reldiff = (cd2_avg - cd_avg) / cd_avg * 100.0 cl_reldiff = (cl2_avg - cl_avg) / cl_avg * 100.0
return v3 / numpy.linalg.norm(v3) # Set simulation directory and data directory. simudir = pathlib.Path(__file__).absolute().parents[1] datadir = simudir / 'output' # Create the wing kinematics. wing = rodney.WingKinematics(Re=200.0, St=0.6, psi=110.0, nt_period=2000) # Compute the cycle-averaged thrust. filepath = datadir / 'forces-0.txt' t, fx, _, _ = petibmpy.read_forces(filepath) thrust = -fx # switch from drag to thrust time_limits = (4 * wing.T, 5 * wing.T) # interval to consider for average thrust_avg, = petibmpy.get_time_averaged_values(t, thrust, limits=time_limits) # Compute the cycle-averaged thrust coefficient. rho, U_inf, A_plan = (getattr(wing, name) for name in ('rho', 'U_inf', 'A_plan')) scale = 1 / (0.5 * rho * U_inf**2 * A_plan) ct, = petibmpy.get_force_coefficients(thrust, coeff=scale) ct_avg, = petibmpy.get_time_averaged_values(t, ct, limits=time_limits) # Load original boundary coordinates from file. filepath = simudir / 'wing.body' wing.load_body(filepath, skiprows=1) # Compute surface area associated with each Lagrangian marker. ds = wing.A_plan / wing.size
import petibmpy show_figure = True # display the Matplotlib figure save_figure = True # save the Matplotlib figure as PNG rootdir = pathlib.Path(__file__).absolute().parents[1] # Load forces and compute mean values for each angle of inclination. time_limits = (15.0, 20.0) angles = numpy.arange(0, 90 + 1, 10, dtype=numpy.int32) cd, cl = [], [] for angle in angles: simudir = rootdir / f'aoa{angle}' filepath = simudir / 'output' / 'forces-0.txt' t, fx, fy, _ = petibmpy.read_forces(filepath) fx_mean, fy_mean = petibmpy.get_time_averaged_values(t, fx, fy, limits=time_limits) cd.append(fx_mean) cl.append(fy_mean) # Load experimental data from Taira et al. (2007). datadir = rootdir.parents[2] / 'data' filepath = datadir / 'taira_et_al_2007_flatplateRe100AR2_cd_exp.dat' with open(filepath, 'r') as infile: cd_taira_exp = numpy.loadtxt(infile, unpack=True) filepath = datadir / 'taira_et_al_2007_flatplateRe100AR2_cl_exp.dat' with open(filepath, 'r') as infile: cl_taira_exp = numpy.loadtxt(infile, unpack=True) # Load numerical data from Taira et al. (2007). filepath = datadir / 'taira_et_al_2007_flatplateRe100AR2_cd_num.dat'