def evolve_model(self, time): self.code.stopping_conditions.number_of_steps_detection.disable() self.code.stopping_conditions.number_of_steps_detection.enable() epsilon = 1e-12 | units.s while self.code.model_time + epsilon < time: self.code.evolve_model(time) if 0: # plot for debugging phi = self.code.grid.gravitational_potential[:, :, 0] figure = pyplot.figure(figsize=(10, 5)) plot = figure.add_subplot(1, 1, 1) plot.imshow(phi.value_in(units.m**2 / units.s**2)) pyplot.show() print phi[:, 1][0:10] self.P0 = phi
def main(): number_of_grid_points = 400 name_of_the_code = "athena" model = CalculateKelvinHelmholtzInstability( number_of_grid_points=number_of_grid_points, number_of_workers=1, name_of_the_code=name_of_the_code ) if not IS_PLOT_AVAILABLE: return grids = model.get_solution_at_time(1.0 | time) rho = grids[0].rho[..., ..., 0].value_in(density) figure = pyplot.figure(figsize=(20, 20)) plot = figure.add_subplot(1, 1, 1) plot.imshow(rho, origin="lower") figure.savefig("kelvin_helmholtz_{0}_{1}.png".format(name_of_the_code, number_of_grid_points)) pyplot.show()
def evolve_model(self, time): self.code.stopping_conditions.number_of_steps_detection.disable() self.code.stopping_conditions.number_of_steps_detection.enable() epsilon = 1e-12 | units.s while self.code.model_time + epsilon < time: self.code.evolve_model(time) if 0: # plot for debugging phi = self.code.grid.gravitational_potential[:, :, 0] figure = pyplot.figure(figsize=(10, 5)) plot = figure.add_subplot(1, 1, 1) plot.imshow(phi.value_in(units.m**2 / units.s**2)) pyplot.show() print(phi[:, 1][0:10]) self.P0 = phi
def main(): number_of_grid_points = 400 name_of_the_code = 'athena' model = CalculateKelvinHelmholtzInstability( number_of_grid_points=number_of_grid_points, number_of_workers=1, name_of_the_code=name_of_the_code) if not IS_PLOT_AVAILABLE: return grids = model.get_solution_at_time(1.0 | time) rho = grids[0].rho[..., ..., 0].value_in(density) figure = pyplot.figure(figsize=(20, 20)) plot = figure.add_subplot(1, 1, 1) plot.imshow(rho, origin='lower') figure.savefig('kelvin_helmholtz_{0}_{1}.png'.format( name_of_the_code, number_of_grid_points)) pyplot.show()
def gravity_for_code(self, field, grid): x = field.x.flatten() y = field.y.flatten() z = field.z.flatten() rho = field.rho.flatten() cell_size = (self.length_scale / self.ncells) cell_volume = cell_size * cell_size * (1 | units.cm) epsilon_squared = cell_size ** 2 cell_mass = rho * cell_volume for cell in grid.iter_cells(): dx = x - cell.x dy = y - cell.y dz = z - cell.z r_squared = (dx**2 + dy**2 + dz**2 + epsilon_squared) r = r_squared.sqrt() cell.potential = constants.G * (cell_mass / r).sum() phi = grid.potential[:, :, 0] figure = pyplot.figure(figsize=(10, 5)) plot = figure.add_subplot(1, 1, 1) plot.imshow(phi.value_in(units.m**2 / units.s**2)) pyplot.show()
def calculate_potential_for_grid(self, grid, field): x = field.x.flatten() x = field.x[:, 0, 0] y = field.y[0, :, 0] # we assume constant grid spacing so # we just create a sample space using # the number of points in x and y nx = len(x) ny = len(y) dx = x[1] - x[0] dy = y[1] - y[0] # # wavenumbers from online examples # kx = (2 * numpy.pi) * numpy.fft.fftfreq(nx, d = dx ) * (1 | units.m) # ky = (2 * numpy.pi) * numpy.fft.fftfreq(ny, d = dy ) * (1 | units.m) # # wavenumbers as calculated in athena dkx = 2.0*numpy.pi/nx dky = 2.0*numpy.pi/ny kx = ((((2.0*numpy.cos(numpy.arange(nx) * dkx))-2.0)/(dx**2)) ).value_in(units.m**-2) ky = ((((2.0*numpy.cos(numpy.arange(ny) * dky))-2.0)/(dy**2)) ).value_in(units.m**-2) kx_grid, ky_grid = numpy.meshgrid(kx, ky) # convert rho to 2d field rho = field.rho[:, :, 0] # use rho0 as mean, should be equal to rho.mean() # but we are comparing with athena and # want the most accurate solution rho_mean = self.rho0 # field.rho.mean() # to remove division by zero kx_grid[0][0] = 1 ky_grid[0][0] = 1 # for poisson solver the source term (gravity) # has to sum to zero over the field # we can ensure this by subtracting the mean from rho rho -= rho_mean gravity_function = 4 * numpy.pi * constants.G * rho gravity_function = gravity_function.value_in(units.s ** -2) gravity_function_fourier_space = numpy.fft.fftn(gravity_function) phi_fourier_space = gravity_function_fourier_space / \ (kx_grid + ky_grid) # 0,0 was divided by zero, should just be zero phi_fourier_space[0, 0] = 0 phi = numpy.fft.ifftn(phi_fourier_space).real # we removed the units for fft, replace these phi = phi | units.m**2 / units.s**2 if 0: # plot for debugging phi_delta = phi # - self.P0 figure = pyplot.figure(figsize=(10, 5)) plot = figure.add_subplot(1, 2, 1) plot.imshow(phi_delta.value_in(units.m**2 / units.s**2)[1:, 1:]) plot = figure.add_subplot(1, 2, 2) plot.imshow( (phi - self.P0).value_in(units.m**2 / units.s**2)[1:, 1:]) pyplot.show() print phi[:, 1][0:10] print (phi[:, 1][0:10] - self.P0[:, 1][0:10]) / phi[:, 1][0:10]
def calculate_potential_for_grid(self, grid, field): x = field.x.flatten() x = field.x[:, 0, 0] y = field.y[0, :, 0] # we assume constant grid spacing so # we just create a sample space using # the number of points in x and y nx = len(x) ny = len(y) dx = x[1] - x[0] dy = y[1] - y[0] # # wavenumbers from online examples # kx = (2 * numpy.pi) * numpy.fft.fftfreq(nx, d = dx ) * (1 | units.m) # ky = (2 * numpy.pi) * numpy.fft.fftfreq(ny, d = dy ) * (1 | units.m) # # wavenumbers as calculated in athena dkx = 2.0*numpy.pi/nx dky = 2.0*numpy.pi/ny kx = ((((2.0*numpy.cos(numpy.arange(nx) * dkx))-2.0)/(dx**2)) ).value_in(units.m**-2) ky = ((((2.0*numpy.cos(numpy.arange(ny) * dky))-2.0)/(dy**2)) ).value_in(units.m**-2) kx_grid, ky_grid = numpy.meshgrid(kx, ky) # convert rho to 2d field rho = field.rho[:, :, 0] # use rho0 as mean, should be equal to rho.mean() # but we are comparing with athena and # want the most accurate solution rho_mean = self.rho0 # field.rho.mean() # to remove division by zero kx_grid[0][0] = 1 ky_grid[0][0] = 1 # for poisson solver the source term (gravity) # has to sum to zero over the field # we can ensure this by subtracting the mean from rho rho -= rho_mean gravity_function = 4 * numpy.pi * constants.G * rho gravity_function = gravity_function.value_in(units.s ** -2) gravity_function_fourier_space = numpy.fft.fftn(gravity_function) phi_fourier_space = gravity_function_fourier_space / \ (kx_grid + ky_grid) # 0,0 was divided by zero, should just be zero phi_fourier_space[0, 0] = 0 phi = numpy.fft.ifftn(phi_fourier_space).real # we removed the units for fft, replace these phi = phi | units.m**2 / units.s**2 if 0: # plot for debugging phi_delta = phi # - self.P0 figure = pyplot.figure(figsize=(10, 5)) plot = figure.add_subplot(1, 2, 1) plot.imshow(phi_delta.value_in(units.m**2 / units.s**2)[1:, 1:]) plot = figure.add_subplot(1, 2, 2) plot.imshow( (phi - self.P0).value_in(units.m**2 / units.s**2)[1:, 1:]) pyplot.show() print(phi[:, 1][0:10]) print((phi[:, 1][0:10] - self.P0[:, 1][0:10]) / phi[:, 1][0:10])