diff --git a/test.py b/test.py deleted file mode 100755 index 9ee45b5da5cc0dfba494d9930a0c35276dca319f..0000000000000000000000000000000000000000 --- a/test.py +++ /dev/null @@ -1,507 +0,0 @@ -#! /usr/bin/env python2 -######################################################################## -# -# Copyright 2015 Max Planck Institute for Dynamics and SelfOrganization -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Contact: Cristian.Lalescu@ds.mpg.de -# -######################################################################## - - -import os -import subprocess -import argparse -import pickle - -import numpy as np -from mpl_toolkits.mplot3d import axes3d -import matplotlib.pyplot as plt -import h5py - -import bfps -from bfps import fluid_resize - -def Kolmogorov_flow_test_broken(opt): - c = convergence_test(name = 'Kflow_test') - c.parameters['nx'] = opt.n - c.parameters['ny'] = opt.n - c.parameters['nz'] = opt.n - c.parameters['nu'] = 1.0 - c.parameters['dt'] = 0.02 - c.parameters['niter_todo'] = opt.nsteps - if opt.run: - np.random.seed(7547) - Kdata00 = generate_data_3D(opt.n, p = 1.).astype(np.complex64) - Kdata01 = generate_data_3D(opt.n, p = 1.).astype(np.complex64) - Kdata02 = generate_data_3D(opt.n, p = 1.).astype(np.complex64) - Kdata0 = np.zeros( - Kdata00.shape + (3,), - Kdata00.dtype) - Kdata0[..., 0] = Kdata00 - Kdata0[..., 1] = Kdata01 - Kdata0[..., 2] = Kdata02 - c.fill_up_fluid_code() - c.finalize_code() - c.write_src() - c.write_par() - Kdata0.tofile("test_cvorticity_i00000") - c.run(ncpu = opt.ncpu) - Rdata = np.fromfile( - 'test_rvorticity_i00000', - dtype = np.float32).reshape(opt.n, opt.n, opt.n, 3) - tdata = Rdata.transpose(3, 0, 1, 2).copy() - dtype = pickle.load(open(c.name + '_dtype.pickle')) - stats = np.fromfile('test_stats.bin', dtype = dtype) - fig = plt.figure(figsize = (12,6)) - a = fig.add_subplot(121) - a.plot(stats['t'], stats['energy']) - a = fig.add_subplot(122) - a.plot(stats['t'], stats['enstrophy']) - fig.savefig('test.pdf', format = 'pdf') - - fig = plt.figure(figsize=(12, 12)) - a = fig.add_subplot(221) - c.plot_vel_cut(a, - field = 'velocity', - iteration = 0) - a = fig.add_subplot(222) - a.set_axis_off() - c.plot_vel_cut(a, - field = 'vorticity', - iteration = 0) - a = fig.add_subplot(223) - ufin = c.plot_vel_cut(a, - field = 'velocity', - iteration = stats.shape[0]-1) - a = fig.add_subplot(224) - vfin = c.plot_vel_cut(a, - field = 'vorticity', - iteration = stats.shape[0]-1) - fig.savefig('field_cut.pdf', format = 'pdf') - - fig = plt.figure() - a = fig.add_subplot(111) - ycoord = c.get_coord('y') - a.plot(ycoord, ufin[0, :, 0, 0]) - amp = c.parameters['famplitude'] / (c.parameters['fmode']**2 * c.parameters['nu']) - a.plot(ycoord, amp*np.sin(ycoord), dashes = (2, 2)) - a.plot(ycoord, vfin[0, :, 0, 2]) - a.plot(ycoord, -np.cos(ycoord), dashes = (2, 2)) - a.set_xticks(np.linspace(.0, 2*np.pi, 9)) - a.set_xlim(.0, 2*np.pi) - a.grid() - fig.savefig('ux_vs_y.pdf', format = 'pdf') - - fig = plt.figure(figsize=(12, 12)) - tmp = np.fromfile('test_cvelocity_i{0:0>5x}'.format(stats.shape[0]-1), - dtype = np.complex64).reshape(opt.n, opt.n, opt.n/2+1, 3) - a = fig.add_subplot(321) - a.plot(np.sum(np.abs(tmp), axis = (1, 2))) - a.set_yscale('log') - a = fig.add_subplot(323) - a.plot(np.sum(np.abs(tmp), axis = (0, 2))) - a.set_yscale('log') - a = fig.add_subplot(325) - a.plot(np.sum(np.abs(tmp), axis = (0, 1))) - a.set_yscale('log') - a = fig.add_subplot(322) - tmp = np.fromfile('test_cvorticity_i{0:0>5x}'.format(stats.shape[0]-1), - dtype = np.complex64).reshape(opt.n, opt.n, opt.n/2+1, 3) - a.plot(np.sum(np.abs(tmp), axis = (1, 2))) - a.set_yscale('log') - a = fig.add_subplot(324) - a.plot(np.sum(np.abs(tmp), axis = (0, 2))) - a.set_yscale('log') - a = fig.add_subplot(326) - a.plot(np.sum(np.abs(tmp), axis = (0, 1))) - a.set_yscale('log') - fig.savefig('cvort.pdf', format = 'pdf') - return None - -def double(opt): - old_simname = 'N{0:0>3x}'.format(opt.n) - new_simname = 'N{0:0>3x}'.format(opt.n*2) - c = fluid_resize( - work_dir = opt.work_dir + '/resize', - simname = old_simname, - dtype = opt.precision) - c.parameters['nx'] = opt.n - c.parameters['ny'] = opt.n - c.parameters['nz'] = opt.n - c.parameters['dst_nx'] = 2*opt.n - c.parameters['dst_ny'] = 2*opt.n - c.parameters['dst_nz'] = 2*opt.n - c.parameters['dst_simname'] = new_simname - c.write_src() - c.set_host_info({'type' : 'pc'}) - if not os.path.isdir(os.path.join(opt.work_dir, 'resize')): - os.mkdir(os.path.join(opt.work_dir, 'resize')) - c.write_par() - cp_command = ('cp {0}/test_cvorticity_i{1:0>5x} {2}/{3}_cvorticity_i{1:0>5x}'.format( - opt.work_dir + '/' + old_simname, opt.iteration, opt.work_dir + '/resize', old_simname)) - subprocess.call([cp_command], shell = True) - c.run(ncpu = opt.ncpu, - err_file = 'err_' + old_simname + '_' + new_simname, - out_file = 'out_' + old_simname + '_' + new_simname) - if not os.path.isdir(os.path.join(opt.work_dir, new_simname)): - os.mkdir(os.path.join(opt.work_dir, new_simname)) - cp_command = ('cp {2}/{3}_cvorticity_i{1:0>5x} {0}/test_cvorticity_i{1:0>5x}'.format( - opt.work_dir + '/' + new_simname, 0, opt.work_dir + '/resize', new_simname)) - subprocess.call([cp_command], shell = True) - return None - -def NSlaunch( - opt, - nu = None, - tracer_state_file = None): - c = bfps.NavierStokes( - work_dir = opt.work_dir, - fluid_precision = opt.precision) - assert((opt.nsteps % 4) == 0) - c.parameters['nx'] = opt.n - c.parameters['ny'] = opt.n - c.parameters['nz'] = opt.n - if type(nu) == type(None): - c.parameters['nu'] = 5.5*opt.n**(-4./3) - else: - c.parameters['nu'] = nu - c.parameters['dt'] = 5e-3 * (64. / opt.n) - c.parameters['niter_todo'] = opt.nsteps - c.parameters['niter_out'] = opt.nsteps - c.parameters['niter_part'] = 1 - c.parameters['famplitude'] = 0.2 - c.parameters['nparticles'] = 8 - c.add_particles(kcut = 'fs->kM/2') - c.add_particles(integration_steps = 1) - c.add_particles(integration_steps = 2) - c.add_particles(integration_steps = 3) - c.add_particles(integration_steps = 4) - c.add_particles(integration_steps = 5) - c.add_particles(integration_steps = 6) - c.fill_up_fluid_code() - c.finalize_code() - c.write_src() - c.write_par() - c.set_host_info({'type' : 'pc'}) - if opt.run: - if opt.iteration == 0 and opt.initialize: - c.generate_vector_field(write_to_file = True) - if opt.iteration == 0: - for species in range(c.particle_species): - if type(tracer_state_file) == type(None): - data = None - else: - data = tracer_state_file['particles/tracers{0}/state'.format(species)][0] - c.generate_tracer_state( - species = species, - write_to_file = False, - testing = True, - rseed = 3284, - data = data) - c.run(ncpu = opt.ncpu, - njobs = opt.njobs) - return c - -def convergence_test(opt): - ### test Navier Stokes convergence - # first, run code three times, doubling and quadrupling the resolution - # initial condition and viscosity must be the same! - default_wd = opt.work_dir - opt.work_dir = default_wd + '/N{0:0>3x}'.format(opt.n) - c0 = NSlaunch(opt) - opt.initialize = False - opt.work_dir = default_wd - double(opt) - opt.iteration = 0 - opt.n *= 2 - opt.nsteps *= 2 - opt.ncpu *= 2 - opt.work_dir = default_wd + '/N{0:0>3x}'.format(opt.n) - c1 = NSlaunch( - opt, - nu = c0.parameters['nu'], - tracer_state_file = h5py.File(os.path.join(c0.work_dir, c0.simname + '.h5'), 'r')) - opt.work_dir = default_wd - double(opt) - opt.n *= 2 - opt.nsteps *= 2 - opt.ncpu *= 2 - opt.work_dir = default_wd + '/N{0:0>3x}'.format(opt.n) - c2 = NSlaunch( - opt, - nu = c0.parameters['nu'], - tracer_state_file = h5py.File(os.path.join(c0.work_dir, c0.simname + '.h5'), 'r')) - # get real space fields - converter = bfps.fluid_converter(fluid_precision = opt.precision) - converter.write_src() - converter.set_host_info({'type' : 'pc'}) - for c in [c0, c1, c2]: - converter.work_dir = c.work_dir - converter.simname = c.simname + '_converter' - for key in converter.parameters.keys(): - if key in c.parameters.keys(): - converter.parameters[key] = c.parameters[key] - converter.parameters['fluid_name'] = c.simname - converter.write_par() - converter.run( - ncpu = 2) - c.transpose_frame(iteration = c.parameters['niter_todo']) - # read data - c0.compute_statistics() - c0.set_plt_style({'dashes': (None, None)}) - c1.compute_statistics() - c1.set_plt_style({'dashes': (2, 3)}) - c2.compute_statistics() - c2.set_plt_style({'dashes': (3, 4)}) - for c in [c0, c1, c2]: - c.style.update({'label' : '${0}\\times {1} \\times {2}$'.format(c.parameters['nx'], - c.parameters['ny'], - c.parameters['nz'])}) - # plot slices - def plot_face_contours(axis, field, levels = None): - xx, yy = np.meshgrid(np.linspace(0, 1, field.shape[1]), - np.linspace(0, 1, field.shape[2])) - if type(levels) == type(None): - emin = np.min(field) - emax = np.max(field) - levels = np.linspace(emin + (emax - emin)/20, - emax - (emax - emin)/20, - 20) - cz = axis.contour(xx, yy, field[0], zdir = 'z', offset = 0.0, levels = levels) - xx, yy = np.meshgrid(np.linspace(0, 1, field.shape[0]), - np.linspace(0, 1, field.shape[2])) - cy = axis.contour(xx, field[:, 0], yy, zdir = 'y', offset = 1.0, levels = levels) - xx, yy = np.meshgrid(np.linspace(0, 1, field.shape[0]), - np.linspace(0, 1, field.shape[1])) - cx = axis.contour(field[:, :, 0], xx, yy, zdir = 'x', offset = 0.0, levels = levels) - axis.set_xlim(0, 1) - axis.set_ylim(0, 1) - axis.set_zlim(0, 1) - return levels - def full_face_contours_fig(field_name = 'velocity'): - fig = plt.figure(figsize = (18,6)) - a = fig.add_subplot(131, projection = '3d') - vec = c0.read_rfield(iteration = c0.parameters['niter_todo'], field = field_name) - levels = plot_face_contours(a, .5*np.sum(vec**2, axis = 3)) - a.set_title(c0.style['label']) - a = fig.add_subplot(132, projection = '3d') - vec = c1.read_rfield(iteration = c1.parameters['niter_todo'], field = field_name) - plot_face_contours(a, .5*np.sum(vec**2, axis = 3), levels = levels) - a.set_title(c1.style['label']) - a = fig.add_subplot(133, projection = '3d') - vec = c2.read_rfield(iteration = c2.parameters['niter_todo'], field = field_name) - plot_face_contours(a, .5*np.sum(vec**2, axis = 3), levels = levels) - a.set_title(c2.style['label']) - fig.savefig(field_name + '_contour_' + opt.precision + '.pdf', format = 'pdf') - full_face_contours_fig() - full_face_contours_fig(field_name = 'vorticity') - # plot spectra - def plot_spec(a, c): - for i in range(c.statistics['energy(t, k)'].shape[0]): - a.plot(c.statistics['kshell'], - c.statistics['energy(t, k)'][i], - color = plt.get_cmap('coolwarm')(i*1.0/(c.statistics['energy(t, k)'].shape[0]))) - a.set_xscale('log') - a.set_yscale('log') - a.set_title(c.style['label']) - fig = plt.figure(figsize=(12, 4)) - plot_spec(fig.add_subplot(131), c0) - plot_spec(fig.add_subplot(132), c1) - plot_spec(fig.add_subplot(133), c2) - fig.savefig('spectra_' + opt.precision + '.pdf', format = 'pdf') - # plot energy and enstrophy - fig = plt.figure(figsize = (12, 12)) - a = fig.add_subplot(221) - for c in [c0, c1, c2]: - a.plot(c.statistics['t'], - c.statistics['energy(t)'], - label = c.style['label'], - dashes = c.style['dashes']) - a.set_title('energy') - a.legend(loc = 'best') - a = fig.add_subplot(222) - for c in [c0, c1, c2]: - a.plot(c.statistics['t'], - c.statistics['enstrophy(t)'], - dashes = c.style['dashes']) - a.set_title('enstrophy') - a = fig.add_subplot(223) - for c in [c0, c1, c2]: - a.plot(c.statistics['t'], - c.statistics['kM']*c.statistics['etaK(t)'], - dashes = c.style['dashes']) - a.set_title('$k_M \\eta_K$') - a = fig.add_subplot(224) - for c in [c0, c1, c2]: - a.plot(c.statistics['t'], - c.statistics['vel_max(t)'] * (c.parameters['dt'] * c.parameters['dkx'] / - (2*np.pi / c.parameters['nx'])), - dashes = c.style['dashes']) - a.set_title('$\\frac{\\Delta t \\| u \\|_\infty}{\\Delta x}$') - fig.savefig('convergence_stats_' + opt.precision + '.pdf', format = 'pdf') - ## particle test: - # compute distance between final positions for species 1 - def get_traj_error(species): - e0 = np.abs(c0.trajectories[species][-1, :, :3] - c1.trajectories[species][-1, :, :3]) - e1 = np.abs(c1.trajectories[species][-1, :, :3] - c2.trajectories[species][-1, :, :3]) - return np.array([np.average(np.sqrt(np.sum(e0**2, axis = 1))), - np.average(np.sqrt(np.sum(e1**2, axis = 1)))]) - err = [get_traj_error(i) for i in range(1, c0.particle_species)] - fig = plt.figure() - a = fig.add_subplot(111) - for i in range(1, c0.particle_species): - print('{0} {1}'.format(i, err[i-1])) - a.plot([c0.parameters['dt'], c1.parameters['dt']], - err[i-1], - marker = '.', - label = '${0}$'.format(i)) - a.plot( [c0.parameters['dt'], c1.parameters['dt']], - [c0.parameters['dt'], c1.parameters['dt']], - label = '$\\Delta t$', - dashes = (1,1), - color = (0, 0, 0)) - a.set_xscale('log') - a.set_yscale('log') - a.legend(loc = 'best') - fig.savefig('traj_evdt_' + opt.precision + '.pdf', format = 'pdf') - # plot all trajectories... just in case - for c in [c0, c1, c2]: - fig = plt.figure(figsize=(12,12)) - a = fig.add_subplot(111, projection = '3d') - for t in range(c.parameters['nparticles']): - for i in range(1, c.particle_species): - a.plot(c.trajectories[i][:, t, 0], - c.trajectories[i][:, t, 1], - c.trajectories[i][:, t, 2]) - fig.savefig('traj_N{0:0>3x}_{1}.pdf'.format(c.parameters['nx'], opt.precision), format = 'pdf') - return None - -def plain(opt): - wd = opt.work_dir - opt.work_dir = wd + '/N{0:0>3x}_1'.format(opt.n) - c0 = NSlaunch(opt) - c0.compute_statistics() - opt.work_dir = wd + '/N{0:0>3x}_2'.format(opt.n) - opt.njobs *= 2 - opt.nsteps /= 2 - c1 = NSlaunch(opt) - c1.compute_statistics() - # plot energy and enstrophy - fig = plt.figure(figsize = (12, 12)) - a = fig.add_subplot(221) - c0.set_plt_style({'label' : '1', - 'dashes' : (None, None), - 'color' : (1, 0, 0)}) - c1.set_plt_style({'label' : '2', - 'dashes' : (2, 2), - 'color' : (0, 0, 1)}) - for c in [c0, c1]: - a.plot(c.statistics['t'], - c.statistics['energy(t)'], - label = c.style['label'], - dashes = c.style['dashes'], - color = c.style['color']) - a.set_title('energy') - a.legend(loc = 'best') - a = fig.add_subplot(222) - for c in [c0, c1]: - a.plot(c.statistics['t'], - c.statistics['enstrophy(t)'], - dashes = c.style['dashes'], - color = c.style['color']) - a.set_title('enstrophy') - a = fig.add_subplot(223) - for c in [c0, c1]: - a.plot(c.statistics['t'], - c.statistics['kM']*c.statistics['etaK(t)'], - dashes = c.style['dashes'], - color = c.style['color']) - a.set_title('$k_M \\eta_K$') - a = fig.add_subplot(224) - for c in [c0, c1]: - a.plot(c.statistics['t'], - c.statistics['vel_max(t)'] * (c.parameters['dt'] * c.parameters['dkx'] / - (2*np.pi / c.parameters['nx'])), - dashes = c.style['dashes'], - color = c.style['color']) - a.set_title('$\\frac{\\Delta t \\| u \\|_\infty}{\\Delta x}$') - fig.savefig('plain_stats_{0}.pdf'.format(opt.precision), format = 'pdf') - - fig = plt.figure(figsize = (12, 12)) - a = fig.add_subplot(221) - a.plot(c0.statistics['t'], - c0.statistics['energy(t)'] - c1.statistics['energy(t)']) - a.set_title('energy') - a = fig.add_subplot(222) - a.plot(c0.statistics['t'], - c0.statistics['enstrophy(t)'] - c1.statistics['enstrophy(t)']) - a.set_title('enstrophy') - a = fig.add_subplot(223) - a.plot(c0.statistics['t'], - c0.statistics['kM']*c0.statistics['etaK(t)'] - c1.statistics['kM']*c1.statistics['etaK(t)']) - a.set_title('$k_M \\eta_K$') - a = fig.add_subplot(224) - data0 = c0.statistics['vel_max(t)'] * (c0.parameters['dt'] * c0.parameters['dkx'] / - (2*np.pi / c0.parameters['nx'])) - data1 = c1.statistics['vel_max(t)'] * (c1.parameters['dt'] * c1.parameters['dkx'] / - (2*np.pi / c1.parameters['nx'])) - a.plot(c0.statistics['t'], - data0 - data1) - a.set_title('$\\frac{\\Delta t \\| u \\|_\infty}{\\Delta x}$') - fig.savefig('plain_stat_diffs_{0}.pdf'.format(opt.precision), format = 'pdf') - - # plot trajectory differences - for i in range(c0.particle_species): - fig = plt.figure(figsize=(12, 4)) - for j in range(3): - a = fig.add_subplot(131 + j) - for t in range(c0.parameters['nparticles']): - a.plot(c0.trajectories[i][:, t, j] - c1.trajectories[i][:, t, j]) - fig.savefig('traj_s{0}_{1}.pdf'.format(i, opt.precision), format = 'pdf') - return None - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--run', dest = 'run', action = 'store_true') - parser.add_argument('--initialize', dest = 'initialize', action = 'store_true') - parser.add_argument('--convergence', dest = 'convergence', action = 'store_true') - parser.add_argument('--plain', dest = 'plain', action = 'store_true') - parser.add_argument('--io', dest = 'io', action = 'store_true') - parser.add_argument('-n', - type = int, dest = 'n', default = 64) - parser.add_argument('--iteration', - type = int, dest = 'iteration', default = 0) - parser.add_argument('--ncpu', - type = int, dest = 'ncpu', default = 2) - parser.add_argument('--nsteps', - type = int, dest = 'nsteps', default = 16) - parser.add_argument('--njobs', - type = int, dest = 'njobs', default = 1) - parser.add_argument('--wd', - type = str, dest = 'work_dir', default = 'data') - parser.add_argument('--precision', - type = str, dest = 'precision', default = 'single') - opt = parser.parse_args() - if opt.convergence: - convergence_test(opt) - if opt.plain: - plain(opt) - if opt.io: - c = bfps.test_io(work_dir = opt.work_dir + '/test_io') - c.write_src() - c.write_par() - c.set_host_info({'type' : 'pc'}) - c.run(ncpu = opt.ncpu) - diff --git a/tests/test_base.py b/tests/test_base.py new file mode 100755 index 0000000000000000000000000000000000000000..9ae0af41bf6cf244794cae708f9d8fe1b924d45d --- /dev/null +++ b/tests/test_base.py @@ -0,0 +1,140 @@ +#! /usr/bin/env python2 +######################################################################## +# +# Copyright 2015 Max Planck Institute for Dynamics and SelfOrganization +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Contact: Cristian.Lalescu@ds.mpg.de +# +######################################################################## + + +import os +import subprocess +import argparse +import pickle + +import numpy as np +from mpl_toolkits.mplot3d import axes3d +import matplotlib.pyplot as plt +import h5py + +import bfps +from bfps import fluid_resize + +parser = argparse.ArgumentParser() +parser.add_argument('--run', dest = 'run', action = 'store_true') +parser.add_argument('--initialize', dest = 'initialize', action = 'store_true') +parser.add_argument('-n', + type = int, dest = 'n', default = 64) +parser.add_argument('--iteration', + type = int, dest = 'iteration', default = 0) +parser.add_argument('--ncpu', + type = int, dest = 'ncpu', default = 2) +parser.add_argument('--nsteps', + type = int, dest = 'nsteps', default = 16) +parser.add_argument('--njobs', + type = int, dest = 'njobs', default = 1) +parser.add_argument('--wd', + type = str, dest = 'work_dir', default = 'data') +parser.add_argument('--precision', + type = str, dest = 'precision', default = 'single') + +def double(opt): + old_simname = 'N{0:0>3x}'.format(opt.n) + new_simname = 'N{0:0>3x}'.format(opt.n*2) + c = fluid_resize( + work_dir = opt.work_dir + '/resize', + simname = old_simname, + dtype = opt.precision) + c.parameters['nx'] = opt.n + c.parameters['ny'] = opt.n + c.parameters['nz'] = opt.n + c.parameters['dst_nx'] = 2*opt.n + c.parameters['dst_ny'] = 2*opt.n + c.parameters['dst_nz'] = 2*opt.n + c.parameters['dst_simname'] = new_simname + c.write_src() + c.set_host_info({'type' : 'pc'}) + if not os.path.isdir(os.path.join(opt.work_dir, 'resize')): + os.mkdir(os.path.join(opt.work_dir, 'resize')) + c.write_par() + cp_command = ('cp {0}/test_cvorticity_i{1:0>5x} {2}/{3}_cvorticity_i{1:0>5x}'.format( + opt.work_dir + '/' + old_simname, opt.iteration, opt.work_dir + '/resize', old_simname)) + subprocess.call([cp_command], shell = True) + c.run(ncpu = opt.ncpu, + err_file = 'err_' + old_simname + '_' + new_simname, + out_file = 'out_' + old_simname + '_' + new_simname) + if not os.path.isdir(os.path.join(opt.work_dir, new_simname)): + os.mkdir(os.path.join(opt.work_dir, new_simname)) + cp_command = ('cp {2}/{3}_cvorticity_i{1:0>5x} {0}/test_cvorticity_i{1:0>5x}'.format( + opt.work_dir + '/' + new_simname, 0, opt.work_dir + '/resize', new_simname)) + subprocess.call([cp_command], shell = True) + return None + +def NSlaunch( + opt, + nu = None, + tracer_state_file = None): + c = bfps.NavierStokes( + work_dir = opt.work_dir, + fluid_precision = opt.precision) + assert((opt.nsteps % 4) == 0) + c.parameters['nx'] = opt.n + c.parameters['ny'] = opt.n + c.parameters['nz'] = opt.n + if type(nu) == type(None): + c.parameters['nu'] = 5.5*opt.n**(-4./3) + else: + c.parameters['nu'] = nu + c.parameters['dt'] = 5e-3 * (64. / opt.n) + c.parameters['niter_todo'] = opt.nsteps + c.parameters['niter_out'] = opt.nsteps + c.parameters['niter_part'] = 1 + c.parameters['famplitude'] = 0.2 + c.parameters['nparticles'] = 8 + c.add_particles(kcut = 'fs->kM/2') + c.add_particles(integration_steps = 1) + c.add_particles(integration_steps = 2) + c.add_particles(integration_steps = 3) + c.add_particles(integration_steps = 4) + c.add_particles(integration_steps = 5) + c.add_particles(integration_steps = 6) + c.fill_up_fluid_code() + c.finalize_code() + c.write_src() + c.write_par() + c.set_host_info({'type' : 'pc'}) + if opt.run: + if opt.iteration == 0 and opt.initialize: + c.generate_vector_field(write_to_file = True) + if opt.iteration == 0: + for species in range(c.particle_species): + if type(tracer_state_file) == type(None): + data = None + else: + data = tracer_state_file['particles/tracers{0}/state'.format(species)][0] + c.generate_tracer_state( + species = species, + write_to_file = False, + testing = True, + rseed = 3284, + data = data) + c.run(ncpu = opt.ncpu, + njobs = opt.njobs) + return c + +if __name__ == '__main__': + print('this file doesn\'t do anything') + diff --git a/tests/test_convergence.py b/tests/test_convergence.py new file mode 100755 index 0000000000000000000000000000000000000000..7b20af01c97263958dc756dbdd002682e01974db --- /dev/null +++ b/tests/test_convergence.py @@ -0,0 +1,201 @@ +#! /usr/bin/env python2 +######################################################################## +# +# Copyright 2015 Max Planck Institute for Dynamics and SelfOrganization +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Contact: Cristian.Lalescu@ds.mpg.de +# +######################################################################## + +from test_base import * + +def convergence_test(opt): + ### test Navier Stokes convergence + # first, run code three times, doubling and quadrupling the resolution + # initial condition and viscosity must be the same! + default_wd = opt.work_dir + opt.work_dir = default_wd + '/N{0:0>3x}'.format(opt.n) + c0 = NSlaunch(opt) + opt.initialize = False + opt.work_dir = default_wd + double(opt) + opt.iteration = 0 + opt.n *= 2 + opt.nsteps *= 2 + opt.ncpu *= 2 + opt.work_dir = default_wd + '/N{0:0>3x}'.format(opt.n) + c1 = NSlaunch( + opt, + nu = c0.parameters['nu'], + tracer_state_file = h5py.File(os.path.join(c0.work_dir, c0.simname + '.h5'), 'r')) + opt.work_dir = default_wd + double(opt) + opt.n *= 2 + opt.nsteps *= 2 + opt.ncpu *= 2 + opt.work_dir = default_wd + '/N{0:0>3x}'.format(opt.n) + c2 = NSlaunch( + opt, + nu = c0.parameters['nu'], + tracer_state_file = h5py.File(os.path.join(c0.work_dir, c0.simname + '.h5'), 'r')) + # get real space fields + converter = bfps.fluid_converter(fluid_precision = opt.precision) + converter.write_src() + converter.set_host_info({'type' : 'pc'}) + for c in [c0, c1, c2]: + converter.work_dir = c.work_dir + converter.simname = c.simname + '_converter' + for key in converter.parameters.keys(): + if key in c.parameters.keys(): + converter.parameters[key] = c.parameters[key] + converter.parameters['fluid_name'] = c.simname + converter.write_par() + converter.run( + ncpu = 2) + c.transpose_frame(iteration = c.parameters['niter_todo']) + # read data + c0.compute_statistics() + c0.set_plt_style({'dashes': (None, None)}) + c1.compute_statistics() + c1.set_plt_style({'dashes': (2, 3)}) + c2.compute_statistics() + c2.set_plt_style({'dashes': (3, 4)}) + for c in [c0, c1, c2]: + c.style.update({'label' : '${0}\\times {1} \\times {2}$'.format(c.parameters['nx'], + c.parameters['ny'], + c.parameters['nz'])}) + # plot slices + def plot_face_contours(axis, field, levels = None): + xx, yy = np.meshgrid(np.linspace(0, 1, field.shape[1]), + np.linspace(0, 1, field.shape[2])) + if type(levels) == type(None): + emin = np.min(field) + emax = np.max(field) + levels = np.linspace(emin + (emax - emin)/20, + emax - (emax - emin)/20, + 20) + cz = axis.contour(xx, yy, field[0], zdir = 'z', offset = 0.0, levels = levels) + xx, yy = np.meshgrid(np.linspace(0, 1, field.shape[0]), + np.linspace(0, 1, field.shape[2])) + cy = axis.contour(xx, field[:, 0], yy, zdir = 'y', offset = 1.0, levels = levels) + xx, yy = np.meshgrid(np.linspace(0, 1, field.shape[0]), + np.linspace(0, 1, field.shape[1])) + cx = axis.contour(field[:, :, 0], xx, yy, zdir = 'x', offset = 0.0, levels = levels) + axis.set_xlim(0, 1) + axis.set_ylim(0, 1) + axis.set_zlim(0, 1) + return levels + def full_face_contours_fig(field_name = 'velocity'): + fig = plt.figure(figsize = (18,6)) + a = fig.add_subplot(131, projection = '3d') + vec = c0.read_rfield(iteration = c0.parameters['niter_todo'], field = field_name) + levels = plot_face_contours(a, .5*np.sum(vec**2, axis = 3)) + a.set_title(c0.style['label']) + a = fig.add_subplot(132, projection = '3d') + vec = c1.read_rfield(iteration = c1.parameters['niter_todo'], field = field_name) + plot_face_contours(a, .5*np.sum(vec**2, axis = 3), levels = levels) + a.set_title(c1.style['label']) + a = fig.add_subplot(133, projection = '3d') + vec = c2.read_rfield(iteration = c2.parameters['niter_todo'], field = field_name) + plot_face_contours(a, .5*np.sum(vec**2, axis = 3), levels = levels) + a.set_title(c2.style['label']) + fig.savefig(field_name + '_contour_' + opt.precision + '.pdf', format = 'pdf') + full_face_contours_fig() + full_face_contours_fig(field_name = 'vorticity') + # plot spectra + def plot_spec(a, c): + for i in range(c.statistics['energy(t, k)'].shape[0]): + a.plot(c.statistics['kshell'], + c.statistics['energy(t, k)'][i], + color = plt.get_cmap('coolwarm')(i*1.0/(c.statistics['energy(t, k)'].shape[0]))) + a.set_xscale('log') + a.set_yscale('log') + a.set_title(c.style['label']) + fig = plt.figure(figsize=(12, 4)) + plot_spec(fig.add_subplot(131), c0) + plot_spec(fig.add_subplot(132), c1) + plot_spec(fig.add_subplot(133), c2) + fig.savefig('spectra_' + opt.precision + '.pdf', format = 'pdf') + # plot energy and enstrophy + fig = plt.figure(figsize = (12, 12)) + a = fig.add_subplot(221) + for c in [c0, c1, c2]: + a.plot(c.statistics['t'], + c.statistics['energy(t)'], + label = c.style['label'], + dashes = c.style['dashes']) + a.set_title('energy') + a.legend(loc = 'best') + a = fig.add_subplot(222) + for c in [c0, c1, c2]: + a.plot(c.statistics['t'], + c.statistics['enstrophy(t)'], + dashes = c.style['dashes']) + a.set_title('enstrophy') + a = fig.add_subplot(223) + for c in [c0, c1, c2]: + a.plot(c.statistics['t'], + c.statistics['kM']*c.statistics['etaK(t)'], + dashes = c.style['dashes']) + a.set_title('$k_M \\eta_K$') + a = fig.add_subplot(224) + for c in [c0, c1, c2]: + a.plot(c.statistics['t'], + c.statistics['vel_max(t)'] * (c.parameters['dt'] * c.parameters['dkx'] / + (2*np.pi / c.parameters['nx'])), + dashes = c.style['dashes']) + a.set_title('$\\frac{\\Delta t \\| u \\|_\infty}{\\Delta x}$') + fig.savefig('convergence_stats_' + opt.precision + '.pdf', format = 'pdf') + ## particle test: + # compute distance between final positions for species 1 + def get_traj_error(species): + e0 = np.abs(c0.trajectories[species][-1, :, :3] - c1.trajectories[species][-1, :, :3]) + e1 = np.abs(c1.trajectories[species][-1, :, :3] - c2.trajectories[species][-1, :, :3]) + return np.array([np.average(np.sqrt(np.sum(e0**2, axis = 1))), + np.average(np.sqrt(np.sum(e1**2, axis = 1)))]) + err = [get_traj_error(i) for i in range(1, c0.particle_species)] + fig = plt.figure() + a = fig.add_subplot(111) + for i in range(1, c0.particle_species): + print('{0} {1}'.format(i, err[i-1])) + a.plot([c0.parameters['dt'], c1.parameters['dt']], + err[i-1], + marker = '.', + label = '${0}$'.format(i)) + a.plot( [c0.parameters['dt'], c1.parameters['dt']], + [c0.parameters['dt'], c1.parameters['dt']], + label = '$\\Delta t$', + dashes = (1,1), + color = (0, 0, 0)) + a.set_xscale('log') + a.set_yscale('log') + a.legend(loc = 'best') + fig.savefig('traj_evdt_' + opt.precision + '.pdf', format = 'pdf') + # plot all trajectories... just in case + for c in [c0, c1, c2]: + fig = plt.figure(figsize=(12,12)) + a = fig.add_subplot(111, projection = '3d') + for t in range(c.parameters['nparticles']): + for i in range(1, c.particle_species): + a.plot(c.trajectories[i][:, t, 0], + c.trajectories[i][:, t, 1], + c.trajectories[i][:, t, 2]) + fig.savefig('traj_N{0:0>3x}_{1}.pdf'.format(c.parameters['nx'], opt.precision), format = 'pdf') + return None + +if __name__ == '__main__': + opt = parser.parse_args() + convergence_test(opt) + diff --git a/tests/test_io.py b/tests/test_io.py new file mode 100755 index 0000000000000000000000000000000000000000..5b5d237d80e683dd279b4d86bbdb33f300768deb --- /dev/null +++ b/tests/test_io.py @@ -0,0 +1,31 @@ +#! /usr/bin/env python2 +######################################################################## +# +# Copyright 2015 Max Planck Institute for Dynamics and SelfOrganization +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Contact: Cristian.Lalescu@ds.mpg.de +# +######################################################################## + +from test_base import * + +if __name__ == '__main__': + opt = parser.parse_args() + c = bfps.test_io(work_dir = opt.work_dir + '/test_io') + c.write_src() + c.write_par() + c.set_host_info({'type' : 'pc'}) + c.run(ncpu = opt.ncpu) + diff --git a/tests/test_plain.py b/tests/test_plain.py new file mode 100755 index 0000000000000000000000000000000000000000..6a19ee47c684adc2559b6cca63a22f8867e5598f --- /dev/null +++ b/tests/test_plain.py @@ -0,0 +1,111 @@ +#! /usr/bin/env python2 +######################################################################## +# +# Copyright 2015 Max Planck Institute for Dynamics and SelfOrganization +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Contact: Cristian.Lalescu@ds.mpg.de +# +######################################################################## + +from test_base import * + +def plain(opt): + wd = opt.work_dir + opt.work_dir = wd + '/N{0:0>3x}_1'.format(opt.n) + c0 = NSlaunch(opt) + c0.compute_statistics() + opt.work_dir = wd + '/N{0:0>3x}_2'.format(opt.n) + opt.njobs *= 2 + opt.nsteps /= 2 + c1 = NSlaunch(opt) + c1.compute_statistics() + # plot energy and enstrophy + fig = plt.figure(figsize = (12, 12)) + a = fig.add_subplot(221) + c0.set_plt_style({'label' : '1', + 'dashes' : (None, None), + 'color' : (1, 0, 0)}) + c1.set_plt_style({'label' : '2', + 'dashes' : (2, 2), + 'color' : (0, 0, 1)}) + for c in [c0, c1]: + a.plot(c.statistics['t'], + c.statistics['energy(t)'], + label = c.style['label'], + dashes = c.style['dashes'], + color = c.style['color']) + a.set_title('energy') + a.legend(loc = 'best') + a = fig.add_subplot(222) + for c in [c0, c1]: + a.plot(c.statistics['t'], + c.statistics['enstrophy(t)'], + dashes = c.style['dashes'], + color = c.style['color']) + a.set_title('enstrophy') + a = fig.add_subplot(223) + for c in [c0, c1]: + a.plot(c.statistics['t'], + c.statistics['kM']*c.statistics['etaK(t)'], + dashes = c.style['dashes'], + color = c.style['color']) + a.set_title('$k_M \\eta_K$') + a = fig.add_subplot(224) + for c in [c0, c1]: + a.plot(c.statistics['t'], + c.statistics['vel_max(t)'] * (c.parameters['dt'] * c.parameters['dkx'] / + (2*np.pi / c.parameters['nx'])), + dashes = c.style['dashes'], + color = c.style['color']) + a.set_title('$\\frac{\\Delta t \\| u \\|_\infty}{\\Delta x}$') + fig.savefig('plain_stats_{0}.pdf'.format(opt.precision), format = 'pdf') + + fig = plt.figure(figsize = (12, 12)) + a = fig.add_subplot(221) + a.plot(c0.statistics['t'], + c0.statistics['energy(t)'] - c1.statistics['energy(t)']) + a.set_title('energy') + a = fig.add_subplot(222) + a.plot(c0.statistics['t'], + c0.statistics['enstrophy(t)'] - c1.statistics['enstrophy(t)']) + a.set_title('enstrophy') + a = fig.add_subplot(223) + a.plot(c0.statistics['t'], + c0.statistics['kM']*c0.statistics['etaK(t)'] - c1.statistics['kM']*c1.statistics['etaK(t)']) + a.set_title('$k_M \\eta_K$') + a = fig.add_subplot(224) + data0 = c0.statistics['vel_max(t)'] * (c0.parameters['dt'] * c0.parameters['dkx'] / + (2*np.pi / c0.parameters['nx'])) + data1 = c1.statistics['vel_max(t)'] * (c1.parameters['dt'] * c1.parameters['dkx'] / + (2*np.pi / c1.parameters['nx'])) + a.plot(c0.statistics['t'], + data0 - data1) + a.set_title('$\\frac{\\Delta t \\| u \\|_\infty}{\\Delta x}$') + fig.savefig('plain_stat_diffs_{0}.pdf'.format(opt.precision), format = 'pdf') + + # plot trajectory differences + for i in range(c0.particle_species): + fig = plt.figure(figsize=(12, 4)) + for j in range(3): + a = fig.add_subplot(131 + j) + for t in range(c0.parameters['nparticles']): + a.plot(c0.trajectories[i][:, t, j] - c1.trajectories[i][:, t, j]) + fig.savefig('traj_s{0}_{1}.pdf'.format(i, opt.precision), format = 'pdf') + return None + +if __name__ == '__main__': + opt = parser.parse_args() + plain(opt) +