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
Beispiel #2
0
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()
Beispiel #3
0
    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()
Beispiel #6
0
    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]
Beispiel #8
0
    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])