diff --git a/.gitignore b/.gitignore index 798b187d4b326fb24bd4ccccabf7dc84b9bb20fd..e0e0be67879a54d27efaef9379bc545658c6d1c4 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ config.h.in config.sub ltmain.sh libtool +build src/version_string.h swift*.tar.gz diff --git a/doc/RTD/source/GettingStarted/running_example.rst b/doc/RTD/source/GettingStarted/running_example.rst index 9dfbdd8c8ec98ea59892a551691aa5f230052e2e..a5614fb2a2e2068a8188d82182042feb95251a73 100644 --- a/doc/RTD/source/GettingStarted/running_example.rst +++ b/doc/RTD/source/GettingStarted/running_example.rst @@ -11,7 +11,7 @@ as ``wget`` for grabbing the glass). .. code-block:: bash - cd examples/SodShock_3D + cd examples/HydroTests/SodShock_3D ./getGlass.sh python makeIC.py ../swift --hydro --threads=4 sodShock.yml diff --git a/doc/RTD/source/HydroSchemes/anarchy_sph.rst b/doc/RTD/source/HydroSchemes/anarchy_sph.rst new file mode 100644 index 0000000000000000000000000000000000000000..8d09280039c25608d3664e1a18d9b5c28d3108b6 --- /dev/null +++ b/doc/RTD/source/HydroSchemes/anarchy_sph.rst @@ -0,0 +1,33 @@ +.. ANARCHY-SPH + Josh Borrow 5th April 2018 + +ANARCHY-PU SPH +============== + +This scheme is similar to the one used in the EAGLE code. This scheme +includes: + ++ Durier & Dalla Vecchia (2012) time-step limiter ++ Pressure-Energy SPH ++ Thermal diffusion following Price (2012) ++ A simplified version of the 'Inviscid SPH' artificial viscosity + (Cullen & Denhen 2010). + +More information will be made available in a forthcoming publication. + +The scheme as-implemented in SWIFT is slightly different to the one +implemented in the original EAGLE code: + ++ Pressure-Energy SPH is used instead of Pressure-Entropy SPH ++ Artificial viscosity coefficients have changed -- from minimal + value of 0.1 to 0.0, and from length of 0.1 to 0.25. This + is based on performance of hydrodynamics tests in SWIFT and may + be to do with our choice of smoothing length definition. ++ Recommended kernel changed from Wendland-C2 (with 100 Ngb) to + Quintic Spline (with ~82 Ngb). + + +.. code-block:: bash + + ./configure --with-hydro=anarchy-pu --with-kernel=quintic-spline --disable-hand-vec + diff --git a/doc/RTD/source/HydroSchemes/index.rst b/doc/RTD/source/HydroSchemes/index.rst index 462bb7378162ff1addab3212a6901412195a3377..7331331bda7c28fad2f471dedb1335f1201d4a21 100644 --- a/doc/RTD/source/HydroSchemes/index.rst +++ b/doc/RTD/source/HydroSchemes/index.rst @@ -17,6 +17,7 @@ schemes available in SWIFT, as well as how to implement your own. minimal_sph planetary hopkins_sph + anarchy_sph gizmo adding_your_own diff --git a/examples/Cooling/CoolingRedshiftDependence/.gitignore b/examples/Cooling/CoolingRedshiftDependence/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..60baa9cb833f9e075739f327f4fe68477c84a093 --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/.gitignore @@ -0,0 +1 @@ +data/* diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml new file mode 100644 index 0000000000000000000000000000000000000000..13ed73554936abc824ee990322cfd49464897c5b --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml @@ -0,0 +1,85 @@ +# Define the system of units to use internally. +InternalUnitSystem: + UnitMass_in_cgs: 1.98848e43 # 10^10 M_sun + UnitLength_in_cgs: 3.08567758e24 # 1 Mpc + UnitVelocity_in_cgs: 1e5 # 1 km/s + UnitCurrent_in_cgs: 1 # Amperes + UnitTemp_in_cgs: 1 # Kelvin + +# Cosmological parameters +Cosmology: + h: 0.6777 # Reduced Hubble constant + a_begin: 0.5 # Initial scale-factor of the simulation (z = 1.0) + a_end: 0.5061559 # Final scale factor of the simulation (~ 100 myr) + Omega_m: 0.307 # Matter density parameter + Omega_lambda: 0.693 # Dark-energy density parameter + Omega_b: 0.0455 # Baryon density parameter + +# Parameters governing the time integration +TimeIntegration: + dt_min: 1e-14 + dt_max: 5e-3 + +# Parameters governing the snapshots +Snapshots: + basename: data/redshift_dependence_high_z + delta_time: 1.000122373748838 + scale_factor_first: 0.5 + compression: 4 + +# Parameters governing the conserved quantities statistics +Statistics: + scale_factor_first: 0.5 + delta_time: 1.1 + +# Parameters for the hydrodynamics scheme +SPH: + resolution_eta: 1.2348 # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel). + CFL_condition: 0.1 # Courant-Friedrich-Levy condition for time integration. + minimal_temperature: 100 # K + +# Parameters related to the initial conditions +InitialConditions: + file_name: ./ics_high_z.hdf5 # The file to read + periodic: 1 + +# Parameters for the EAGLE chemistry +EAGLEChemistry: # Solar abundances + init_abundance_metal: 0. + init_abundance_Hydrogen: 0.752 + init_abundance_Helium: 0.248 + init_abundance_Carbon: 0. + init_abundance_Nitrogen: 0. + init_abundance_Oxygen: 0. + init_abundance_Neon: 0. + init_abundance_Magnesium: 0. + init_abundance_Silicon: 0. + init_abundance_Iron: 0. + +# Parameters for the EAGLE cooling +EAGLECooling: + dir_name: ./coolingtables/ + H_reion_z: 11.5 + H_reion_eV_p_H: 2.0 + He_reion_z_centre: 3.5 + He_reion_z_sigma: 0.5 + He_reion_eV_p_H: 2.0 + +# Parameters for the EAGLE "equation of state" +EAGLEEntropyFloor: + Jeans_density_threshold_H_p_cm3: 0.1 # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Jeans_over_density_threshold: 10. # Overdensity above which the EAGLE Jeans limiter entropy floor can kick in. + Jeans_temperature_norm_K: 8000 # Temperature of the EAGLE Jeans limiter entropy floor at the density threshold expressed in Kelvin. + Jeans_gamma_effective: 1.3333333 # Slope the of the EAGLE Jeans limiter entropy floor + Cool_density_threshold_H_p_cm3: 1e-5 # Physical density above which the EAGLE Cool limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Cool_over_density_threshold: 10. # Overdensity above which the EAGLE Cool limiter entropy floor can kick in. + Cool_temperature_norm_K: 8000 # Temperature of the EAGLE Cool limiter entropy floor at the density threshold expressed in Kelvin. + Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor + +LambdaCooling: + lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] + +ConstCooling: + cooling_rate: 1. # Cooling rate (du/dt) (internal units) + min_energy: 1. # Minimal internal energy per unit mass (internal units) + cooling_tstep_mult: 1. # Dimensionless pre-factor for the time-step condition \ No newline at end of file diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml new file mode 100644 index 0000000000000000000000000000000000000000..5b336bc4bf86d2596ec52e84e24da2710d96cb8a --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml @@ -0,0 +1,85 @@ +# Define the system of units to use internally. +InternalUnitSystem: + UnitMass_in_cgs: 1.98848e33 # 10^10 M_sun + UnitLength_in_cgs: 3.08567758e21 # 1 kpc + UnitVelocity_in_cgs: 1 # 1 km/s + UnitCurrent_in_cgs: 1 # Amperes + UnitTemp_in_cgs: 1 # Kelvin + +# Cosmological parameters +Cosmology: + h: 0.6777 # Reduced Hubble constant + a_begin: 0.99009 # Initial scale-factor of the simulation (z = 0.01) + a_end: 0.99700 # Final scale factor of the simulation (~ 100 myr) + Omega_m: 0.307 # Matter density parameter + Omega_lambda: 0.693 # Dark-energy density parameter + Omega_b: 0.0455 # Baryon density parameter + +# Parameters governing the time integration +TimeIntegration: + dt_min: 1e-14 + dt_max: 5e-3 + +# Parameters governing the snapshots +Snapshots: + basename: data/redshift_dependence_low_z + delta_time: 1.0000695206950205 + scale_factor_first: 0.99009 + compression: 4 + +# Parameters governing the conserved quantities statistics +Statistics: + scale_factor_first: 0.99009 + delta_time: 1.1 + +# Parameters for the hydrodynamics scheme +SPH: + resolution_eta: 1.2348 # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel). + CFL_condition: 0.1 # Courant-Friedrich-Levy condition for time integration. + minimal_temperature: 100 # K + +# Parameters related to the initial conditions +InitialConditions: + file_name: ./ics_low_z.hdf5 # The file to read + periodic: 1 + +# Parameters for the EAGLE chemistry +EAGLEChemistry: # Primordial + init_abundance_metal: 0. + init_abundance_Hydrogen: 0.752 + init_abundance_Helium: 0.248 + init_abundance_Carbon: 0. + init_abundance_Nitrogen: 0. + init_abundance_Oxygen: 0. + init_abundance_Neon: 0. + init_abundance_Magnesium: 0. + init_abundance_Silicon: 0. + init_abundance_Iron: 0. + +# Parameters for the EAGLE cooling +EAGLECooling: + dir_name: ./coolingtables/ + H_reion_z: 11.5 + H_reion_eV_p_H: 2.0 + He_reion_z_centre: 3.5 + He_reion_z_sigma: 0.5 + He_reion_eV_p_H: 2.0 + +# Parameters for the EAGLE "equation of state" +EAGLEEntropyFloor: + Jeans_density_threshold_H_p_cm3: 0.1 # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Jeans_over_density_threshold: 10. # Overdensity above which the EAGLE Jeans limiter entropy floor can kick in. + Jeans_temperature_norm_K: 8000 # Temperature of the EAGLE Jeans limiter entropy floor at the density threshold expressed in Kelvin. + Jeans_gamma_effective: 1.3333333 # Slope the of the EAGLE Jeans limiter entropy floor + Cool_density_threshold_H_p_cm3: 1e-5 # Physical density above which the EAGLE Cool limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Cool_over_density_threshold: 10. # Overdensity above which the EAGLE Cool limiter entropy floor can kick in. + Cool_temperature_norm_K: 8000 # Temperature of the EAGLE Cool limiter entropy floor at the density threshold expressed in Kelvin. + Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor + +LambdaCooling: + lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] + +ConstCooling: + cooling_rate: 1. # Cooling rate (du/dt) (internal units) + min_energy: 1. # Minimal internal energy per unit mass (internal units) + cooling_tstep_mult: 1. # Dimensionless pre-factor for the time-step condition diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml new file mode 100644 index 0000000000000000000000000000000000000000..8bce6498432b3782225c7e53397868fc1356a26e --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml @@ -0,0 +1,76 @@ +# Define the system of units to use internally. +InternalUnitSystem: + UnitMass_in_cgs: 1.98848e43 # 10^10 M_sun + UnitLength_in_cgs: 3.08567758e24 # 1 Mpc + UnitVelocity_in_cgs: 1e5 # 1 km/s + UnitCurrent_in_cgs: 1 # Amperes + UnitTemp_in_cgs: 1 # Kelvin + +# Parameters governing the time integration +TimeIntegration: + time_begin: 0. + time_end: 1.02e-4 # ~ 100 myr + dt_min: 1e-14 + dt_max: 5e-5 + +# Parameters governing the snapshots +Snapshots: + basename: data/redshift_dependence_no_z + delta_time: 1.02e-6 + compression: 4 + +# Parameters governing the conserved quantities statistics +Statistics: + delta_time: 1.02e-6 + +# Parameters for the hydrodynamics scheme +SPH: + resolution_eta: 1.2348 # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel). + CFL_condition: 0.1 # Courant-Friedrich-Levy condition for time integration. + minimal_temperature: 100 # K + +# Parameters related to the initial conditions +InitialConditions: + file_name: ./ics_no_z.hdf5 # The file to read + periodic: 1 + +# Parameters for the EAGLE chemistry +EAGLEChemistry: # Solar abundances + init_abundance_metal: 0. + init_abundance_Hydrogen: 0.752 + init_abundance_Helium: 0.248 + init_abundance_Carbon: 0. + init_abundance_Nitrogen: 0. + init_abundance_Oxygen: 0. + init_abundance_Neon: 0. + init_abundance_Magnesium: 0. + init_abundance_Silicon: 0. + init_abundance_Iron: 0. + +# Parameters for the EAGLE cooling +EAGLECooling: + dir_name: ./coolingtables/ + H_reion_z: 11.5 + H_reion_eV_p_H: 2.0 + He_reion_z_centre: 3.5 + He_reion_z_sigma: 0.5 + He_reion_eV_p_H: 2.0 + +# Parameters for the EAGLE "equation of state" +EAGLEEntropyFloor: + Jeans_density_threshold_H_p_cm3: 0.1 # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Jeans_over_density_threshold: 10. # Overdensity above which the EAGLE Jeans limiter entropy floor can kick in. + Jeans_temperature_norm_K: 8000 # Temperature of the EAGLE Jeans limiter entropy floor at the density threshold expressed in Kelvin. + Jeans_gamma_effective: 1.3333333 # Slope the of the EAGLE Jeans limiter entropy floor + Cool_density_threshold_H_p_cm3: 1e-5 # Physical density above which the EAGLE Cool limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Cool_over_density_threshold: 10. # Overdensity above which the EAGLE Cool limiter entropy floor can kick in. + Cool_temperature_norm_K: 8000 # Temperature of the EAGLE Cool limiter entropy floor at the density threshold expressed in Kelvin. + Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor + +LambdaCooling: + lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] + +ConstCooling: + cooling_rate: 1. # Cooling rate (du/dt) (internal units) + min_energy: 1. # Minimal internal energy per unit mass (internal units) + cooling_tstep_mult: 1. # Dimensionless pre-factor for the time-step condition \ No newline at end of file diff --git a/examples/Cooling/CoolingRedshiftDependence/getGlass.sh b/examples/Cooling/CoolingRedshiftDependence/getGlass.sh new file mode 100755 index 0000000000000000000000000000000000000000..01b4474ac21666c843b7abedfa39a76948934911 --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/getGlass.sh @@ -0,0 +1,2 @@ +#!/bin/bash +wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/gravity_glassCube_32.hdf5 diff --git a/examples/Cooling/CoolingRedshiftDependence/makeIC.py b/examples/Cooling/CoolingRedshiftDependence/makeIC.py new file mode 100644 index 0000000000000000000000000000000000000000..61b87566882f1bad9704844b13ae04773a353acd --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/makeIC.py @@ -0,0 +1,124 @@ +""" +Creates a redshift-dependent cooling box such that it always has the same +_physical_ density at the given redshift. +""" + +from swiftsimio import Writer +from swiftsimio.units import cosmo_units + +from unyt import mh, cm, s, K, Mpc, kb +import numpy as np + +import h5py + +# Physics parameters. +boxsize = 1.0 * Mpc +physical_density = 0.1 * mh / cm ** 3 +mu_hydrogen = 0.5 # Fully ionised +temperature = 1e7 * K +gamma = 5.0 / 3.0 + + +def get_coordinates(glass_filename: str) -> np.array: + """ + Gets the coordinates from the glass file. + """ + + with h5py.File(glass_filename, "r") as handle: + coordinates = handle["PartType1/Coordinates"][...] + + return coordinates + + +def generate_ics(redshift: float, filename: str, glass_filename: str) -> None: + """ + Generate initial conditions for the CoolingRedshiftDependence example. + """ + + scale_factor = 1 / (1 + redshift) + comoving_boxsize = boxsize / scale_factor + + glass_coordinates = get_coordinates(glass_filename) + number_of_particles = len(glass_coordinates) + + gas_particle_mass = physical_density * (boxsize ** 3) / number_of_particles + + writer = Writer(cosmo_units, comoving_boxsize) + + writer.gas.coordinates = glass_coordinates * comoving_boxsize + + writer.gas.velocities = np.zeros_like(glass_coordinates) * cm / s + + writer.gas.masses = np.ones(number_of_particles, dtype=float) * gas_particle_mass + + # Leave in physical units; handled by boxsize change. + writer.gas.internal_energy = ( + np.ones(number_of_particles, dtype=float) + * 3.0 / 2.0 + * (temperature * kb) + / (mu_hydrogen * mh) + ) + + writer.gas.generate_smoothing_lengths(boxsize=comoving_boxsize, dimension=3) + + writer.write(filename) + + return + + +if __name__ == "__main__": + """ + Sets up the initial parameters. + """ + + import argparse as ap + + parser = ap.ArgumentParser( + description=""" + Sets up the initial conditions for the cooling test. Takes two + redshifts, and produces two files: ics_high_z.hdf5 and + ics_low_z.hdf5. + """ + ) + + parser.add_argument( + "-a", + "--high", + help="The high redshift to generate initial conditions for. Default: 1.0", + default=1, + type=float, + ) + + parser.add_argument( + "-b", + "--low", + help="The low redshift to generate initial conditions for. Default: 0.01", + default=0.01, + type=float, + ) + + parser.add_argument( + "-n", + "--nocosmo", + help="Generate a non-cosmological box? Default: Truthy", + default=1, + type=bool, + ) + + parser.add_argument( + "-g", + "--glass", + help="Glass filename. Default: gravity_glassCube_32.hdf5", + type=str, + default="gravity_glassCube_32.hdf5", + ) + + args = parser.parse_args() + + generate_ics(args.low, filename="ics_low_z.hdf5", glass_filename=args.glass) + generate_ics(args.high, filename="ics_high_z.hdf5", glass_filename=args.glass) + + if args.nocosmo: + generate_ics(0.0, filename="ics_no_z.hdf5", glass_filename=args.glass) + + exit(0) diff --git a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py new file mode 100644 index 0000000000000000000000000000000000000000..9cde36cb05b88e60b3bf3527f3857a3774bf5dca --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py @@ -0,0 +1,223 @@ +""" +Plots the mean temperature. +""" + +import matplotlib.pyplot as plt + +from swiftsimio import load + +from unyt import Myr, K, mh, cm, erg + +import numpy as np + + +def get_data_dump(metadata): + """ + Gets a big data dump from the SWIFT metadata + """ + + try: + viscosity = metadata.viscosity_info + except: + viscosity = "No info" + + try: + diffusion = metadata.diffusion_info + except: + diffusion = "No info" + + output = ( + "$\\bf{SWIFT}$\n" + + metadata.code_info + + "\n\n" + + "$\\bf{Compiler}$\n" + + metadata.compiler_info + + "\n\n" + + "$\\bf{Hydrodynamics}$\n" + + metadata.hydro_info + + "\n\n" + + "$\\bf{Viscosity}$\n" + + viscosity + + "\n\n" + + "$\\bf{Diffusion}$\n" + + diffusion + ) + + return output + + +def setup_axes(): + """ + Sets up the axes and returns fig, ax + """ + + fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(8, 8)) + + ax = ax.flatten() + + ax[0].semilogy() + ax[2].semilogy() + + ax[1].set_xlabel("Simulation time elapsed [Myr]") + ax[2].set_xlabel("Simulation time elapsed [Myr]") + + ax[0].set_ylabel("Temperature of Universe [K]") + ax[1].set_ylabel("Physical Density of Universe [$n_H$ cm$^{-3}$]") + ax[2].set_ylabel("Physical Energy [erg]") + + for a in ax[:-1]: + a.set_xlim(0, 100) + + fig.tight_layout(pad=0.5) + + return fig, ax + + +def get_data(handle: float, n_snaps: int): + """ + Returns the elapsed simulation time, temperature, and density + """ + + t0 = 0.0 + + times = [] + temps = [] + densities = [] + energies = [] + radiated_energies = [] + + for snap in range(n_snaps): + try: + data = load(f"data/{handle}_{snap:04d}.hdf5") + + if snap == 0: + t0 = data.metadata.t.to(Myr).value + + times.append(data.metadata.t.to(Myr).value - t0) + temps.append(np.mean(data.gas.temperature.to(K).value)) + densities.append( + np.mean(data.gas.density.to(mh / cm ** 3).value) + / (data.metadata.scale_factor ** 3) + ) + + try: + energies.append( + np.mean((data.gas.internal_energy * data.gas.masses).to(erg).value) + * data.metadata.scale_factor ** (2) + ) + radiated_energies.append( + np.mean(data.gas.radiated_energy.to(erg).value) + ) + except AttributeError: + continue + except OSError: + continue + + return times, temps, densities, energies, radiated_energies + + +def get_n_steps(timesteps_filename: str) -> int: + """ + Reads the number of steps from the timesteps file. + """ + + data = np.genfromtxt(timesteps_filename) + + return int(data[-1][0]) + + +def plot_single_data( + handle: str, n_snaps: int, label: str, ax: plt.axes, n_steps: int = 0, run: int = 0 +): + """ + Takes the a single simulation and plots it on the axes. + """ + + data = get_data(handle, n_snaps) + + ax[0].plot(data[0], data[1], label=label, marker="o", ms=2, c=f"C{run}") + + ax[1].plot( + data[0], data[2], label=f"Steps: {n_steps}", marker="o", ms=2, c=f"C{run}" + ) + + if run == 0: + label_energy = "Particle Energy" + label_radiated = "Radiated Energy" + label_sum = "Sum" + else: + label_energy = "" + label_radiated = "" + label_sum = "" + + ax[2].plot(data[0], data[3], label=label_energy, ls="dotted", C=f"C{run}") + + # ax[2].plot(data[0], data[4], label=label_radiated, ls="dashed", C=f"C{run}") + + # ax[2].plot( + # data[0], [x + y for x, y in zip(*data[3:5])], label=label_sum, C=f"C{run}" + # ) + + return + + +def make_plot(handles, names, timestep_names, n_snaps=100): + """ + Makes the whole plot and returns the fig, ax objects. + """ + + fig, ax = setup_axes() + + run = 0 + + for handle, name, timestep_name in zip(handles, names, timestep_names): + try: + n_steps = get_n_steps(timestep_name) + except: + n_steps = "Unknown" + + plot_single_data(handle, n_snaps, name, ax, n_steps=n_steps, run=run) + run += 1 + + ax[0].legend() + ax[1].legend() + ax[2].legend() + + info_axis = ax[-1] + + try: + info = get_data_dump(load(f"data/{handles[0]}_0000.hdf5").metadata) + + info_axis.text( + 0.5, + 0.45, + info, + ha="center", + va="center", + fontsize=7, + transform=info_axis.transAxes, + ) + except OSError: + pass + + info_axis.axis("off") + + return fig, ax + + +if __name__ == "__main__": + """ + Plot everything! + """ + + handles = [ + "redshift_dependence_no_z", + "redshift_dependence_low_z", + "redshift_dependence_high_z", + ] + names = ["No Cosmology", "Low Redshift ($z=0.01$)", "High Redshift ($z=1$)"] + timestep_names = ["timesteps_no.txt", "timesteps_low.txt", "timesteps_high.txt"] + + fig, ax = make_plot(handles, names, timestep_names) + + fig.savefig("redshift_dependence.png", dpi=300) diff --git a/examples/Cooling/CoolingRedshiftDependence/run.sh b/examples/Cooling/CoolingRedshiftDependence/run.sh new file mode 100755 index 0000000000000000000000000000000000000000..c9bf2aea7edd33886219dd4db822d930baff7d47 --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/run.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Generate the initial conditions if they are not present. +if [ ! -e gravity_glassCube_32.hdf5 ] +then + echo "Fetching initial gravity glass file for the constant cosmological box example..." + ./getGlass.sh +fi + +# Fetch the cooling tables +if [ ! -e ics_no_z.hdf5 ] +then + echo "Generating initial conditions for the uniform cosmo box example..." + python3 makeIC.py +fi + +swift_location="../../swift" + +rm data/redshift_dependence_*_z_*.hdf5 + +mkdir data + +# Run SWIFT +$swift_location --hydro --cosmology --cooling --limiter --threads=4 cooling_redshift_dependence_high_z.yml 2>&1 | tee output_high.log +mv timesteps_4.txt timesteps_high.txt +$swift_location --hydro --cosmology --cooling --limiter --threads=4 cooling_redshift_dependence_low_z.yml 2>&1 | tee output_low.log +mv timesteps_4.txt timesteps_low.txt +$swift_location --hydro --cooling --limiter --threads=4 cooling_redshift_dependence_no_z.yml 2>&1 | tee output_no.log +mv timesteps_4.txt timesteps_no.txt + +python3 plotSolution.py diff --git a/examples/Cosmology/ComovingSodShock_3D/plotSolution.py b/examples/Cosmology/ComovingSodShock_3D/plotSolution.py index f05a385e8620b18189d2e7abca8aebb8ae65060e..d85f4be9a49d108d133928a81ea4482fa9099792 100644 --- a/examples/Cosmology/ComovingSodShock_3D/plotSolution.py +++ b/examples/Cosmology/ComovingSodShock_3D/plotSolution.py @@ -88,6 +88,18 @@ S = sim["/PartType0/Entropy"][:] P = sim["/PartType0/Pressure"][:] rho = sim["/PartType0/Density"][:] +try: + diffusion = sim["/PartType0/Diffusion"][:] + plot_diffusion = True +except: + plot_diffusion = False + +try: + viscosity = sim["/PartType0/Viscosity"][:] + plot_viscosity = True +except: + plot_viscosity = False + x_min = -1. x_max = 1. x += x_min @@ -112,6 +124,15 @@ P_sigma_bin = np.sqrt(P2_bin - P_bin**2) S_sigma_bin = np.sqrt(S2_bin - S_bin**2) u_sigma_bin = np.sqrt(u2_bin - u_bin**2) +if plot_diffusion: + alpha_diff_bin,_,_ = stats.binned_statistic(x, diffusion, statistic='mean', bins=x_bin_edge) + alpha2_diff_bin,_,_ = stats.binned_statistic(x, diffusion**2, statistic='mean', bins=x_bin_edge) + alpha_diff_sigma_bin = np.sqrt(alpha2_diff_bin - alpha_diff_bin**2) + +if plot_viscosity: + alpha_visc_bin,_,_ = stats.binned_statistic(x, viscosity, statistic='mean', bins=x_bin_edge) + alpha2_visc_bin,_,_ = stats.binned_statistic(x, viscosity**2, statistic='mean', bins=x_bin_edge) + alpha_visc_sigma_bin = np.sqrt(alpha2_visc_bin - alpha_visc_bin**2) # Analytic solution c_L = sqrt(gas_gamma * P_L / rho_L) # Speed of the rarefaction wave @@ -285,13 +306,26 @@ ylim(0.8, 2.2) # Entropy profile --------------------------------- subplot(235) -plot(x, S, '.', color='r', ms=0.5, alpha=0.2) -plot(x_s, s_s, '--', color='k', alpha=0.8, lw=1.2) -errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) -xlabel("${\\rm{Position}}~x$", labelpad=0) -ylabel("${\\rm{Entropy}}~S$", labelpad=0) xlim(-0.5, 0.5) -ylim(0.8, 3.8) +xlabel("${\\rm{Position}}~x$", labelpad=0) + +if plot_diffusion or plot_viscosity: + if plot_diffusion: + plot(x, diffusion * 100, ".", color='r', ms=0.5, alpha=0.2) + errorbar(x_bin, alpha_diff_bin * 100, yerr=alpha_diff_sigma_bin * 100, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion (100x)") + + if plot_viscosity: + plot(x, viscosity, ".", color='g', ms=0.5, alpha=0.2) + errorbar(x_bin, alpha_visc_bin, yerr=alpha_visc_sigma_bin, fmt=".", ms=8.0, color='y', lw=1.2, label="Viscosity") + + ylabel("${\\rm{Rate~Coefficient}}~\\alpha$", labelpad=0) + legend() +else: + plot(x, S, '.', color='r', ms=0.5, alpha=0.2) + plot(x_s, s_s, '--', color='k', alpha=0.8, lw=1.2) + errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) + ylabel("${\\rm{Entropy}}~S$", labelpad=0) + ylim(0.8, 3.8) # Information ------------------------------------- subplot(236, frameon=False) @@ -312,5 +346,4 @@ ylim(0, 1) xticks([]) yticks([]) -tight_layout() savefig("SodShock.png", dpi=200) diff --git a/examples/Cosmology/ComovingSodShock_3D/sodShock.yml b/examples/Cosmology/ComovingSodShock_3D/sodShock.yml index 2d7a5727cbbc2cd417527ce05d7a8ea8ea05dd71..b5b2ff8fd5571c4093b043c9903398a391e51758 100644 --- a/examples/Cosmology/ComovingSodShock_3D/sodShock.yml +++ b/examples/Cosmology/ComovingSodShock_3D/sodShock.yml @@ -2,13 +2,13 @@ InternalUnitSystem: UnitMass_in_cgs: 2.94e55 # Grams UnitLength_in_cgs: 3.086e18 # pc - UnitVelocity_in_cgs: 1. # km per s + UnitVelocity_in_cgs: 1 # km per s UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin # Parameters governing the time integration TimeIntegration: - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-18 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-3 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots @@ -16,11 +16,13 @@ Snapshots: basename: sodShock # Common part of the name of output files time_first: 0. # Time of the first output (in internal units) delta_time: 1.06638 # Time difference between consecutive outputs (in internal units) + # scale_factor_first: 1.0 scale_factor_first: 0.001 compression: 1 # Parameters governing the conserved quantities statistics Statistics: + scale_factor_first: 1.0 delta_time: 1.02 # Time between statistics output # Parameters for the hydrodynamics scheme @@ -41,3 +43,38 @@ Cosmology: a_begin: 0.001 a_end: 0.00106638 +# Impose primoridal metallicity +EAGLEChemistry: + init_abundance_metal: 0. + init_abundance_Hydrogen: 0.752 + init_abundance_Helium: 0.248 + init_abundance_Carbon: 0.0 + init_abundance_Nitrogen: 0.0 + init_abundance_Oxygen: 0.0 + init_abundance_Neon: 0.0 + init_abundance_Magnesium: 0.0 + init_abundance_Silicon: 0.0 + init_abundance_Iron: 0.0 + +EAGLECooling: + dir_name: ./coolingtables/ + H_reion_z: 11.5 + H_reion_eV_p_H: 2.0 + He_reion_z_centre: 3.5 + He_reion_z_sigma: 0.5 + He_reion_eV_p_H: 2.0 + +# Parameters for the EAGLE "equation of state" +EAGLEEntropyFloor: + Jeans_density_threshold_H_p_cm3: 0.1 # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Jeans_over_density_threshold: 10. # Overdensity above which the EAGLE Jeans limiter entropy floor can kick in. + Jeans_temperature_norm_K: 8000 # Temperature of the EAGLE Jeans limiter entropy floor at the density threshold expressed in Kelvin. + Jeans_gamma_effective: 1.3333333 # Slope the of the EAGLE Jeans limiter entropy floor + Cool_density_threshold_H_p_cm3: 1e-5 # Physical density above which the EAGLE Cool limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Cool_over_density_threshold: 10. # Overdensity above which the EAGLE Cool limiter entropy floor can kick in. + Cool_temperature_norm_K: 8000 # Temperature of the EAGLE Cool limiter entropy floor at the density threshold expressed in Kelvin. + Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor + +LambdaCooling: + lambda_nH2_cgs: 1e-48 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3]) + cooling_tstep_mult: 1.0 # (Optional) Dimensionless pre-factor for the time-step condition. diff --git a/examples/HydroTests/GreshoVortex_3D/plotSolution.py b/examples/HydroTests/GreshoVortex_3D/plotSolution.py index 8fddf148bd169310d5e69ffbfa4a6de099068c69..545440c997d9ebc3ab11562d0a7d9fa143e23ed2 100644 --- a/examples/HydroTests/GreshoVortex_3D/plotSolution.py +++ b/examples/HydroTests/GreshoVortex_3D/plotSolution.py @@ -108,6 +108,18 @@ u = sim["/PartType0/InternalEnergy"][:] S = sim["/PartType0/Entropy"][:] P = sim["/PartType0/Pressure"][:] +try: + diffusion = sim["/PartType0/Diffusion"][:] + plot_diffusion = True +except: + plot_diffusion = False + +try: + viscosity = sim["/PartType0/Viscosity"][:] + plot_viscosity = True +except: + plot_viscosity = False + # Bin te data r_bin_edge = np.arange(0., 1., 0.02) r_bin = 0.5*(r_bin_edge[1:] + r_bin_edge[:-1]) @@ -127,6 +139,15 @@ P_sigma_bin = np.sqrt(P2_bin - P_bin**2) S_sigma_bin = np.sqrt(S2_bin - S_bin**2) u_sigma_bin = np.sqrt(u2_bin - u_bin**2) +if plot_diffusion: + alpha_diff_bin,_,_ = stats.binned_statistic(r, diffusion, statistic='mean', bins=r_bin_edge) + alpha2_diff_bin,_,_ = stats.binned_statistic(r, diffusion**2, statistic='mean', bins=r_bin_edge) + alpha_diff_sigma_bin = np.sqrt(alpha2_diff_bin - alpha_diff_bin**2) + +if plot_viscosity: + alpha_visc_bin,_,_ = stats.binned_statistic(r, viscosity, statistic='mean', bins=r_bin_edge) + alpha2_visc_bin,_,_ = stats.binned_statistic(r, viscosity**2, statistic='mean', bins=r_bin_edge) + alpha_visc_sigma_bin = np.sqrt(alpha2_visc_bin - alpha_visc_bin**2) # Plot the interesting quantities figure() @@ -188,16 +209,32 @@ ylim(7.3, 9.1) # Radial entropy profile -------------------------------- subplot(235) - -plot(r, S, '.', color='r', ms=0.5) -plot(solution_r, solution_s, '--', color='k', alpha=0.8, lw=1.2) -errorbar(r_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) -plot([0.2, 0.2], [-100, 100], ':', color='k', alpha=0.4, lw=1.2) -plot([0.4, 0.4], [-100, 100], ':', color='k', alpha=0.4, lw=1.2) xlabel("${\\rm{Radius}}~r$", labelpad=0) -ylabel("${\\rm{Entropy}}~S$", labelpad=0) + xlim(0, R_max) -ylim(4.9 + P0, P0 + 6.1) + +xlabel("${\\rm{Radius}}~r$", labelpad=0) + + +if plot_diffusion or plot_viscosity: + if plot_diffusion: + plot(r, diffusion, ".", color='r', ms=0.5, alpha=0.2) + errorbar(r_bin, alpha_diff_bin, yerr=alpha_diff_sigma_bin, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion") + + if plot_viscosity: + plot(r, viscosity, ".", color='g', ms=0.5, alpha=0.2) + errorbar(r_bin, alpha_visc_bin, yerr=alpha_visc_sigma_bin, fmt=".", ms=8.0, color='y', lw=1.2, label="Viscosity") + + ylabel("${\\rm{Rate~Coefficient}}~\\alpha$", labelpad=0) + legend() +else: + plot(r, S, '.', color='r', ms=0.5) + plot(solution_r, solution_s, '--', color='k', alpha=0.8, lw=1.2) + errorbar(r_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) + plot([0.2, 0.2], [-100, 100], ':', color='k', alpha=0.4, lw=1.2) + plot([0.4, 0.4], [-100, 100], ':', color='k', alpha=0.4, lw=1.2) + ylabel("${\\rm{Entropy}}~S$", labelpad=0) + ylim(4.9 + P0, P0 + 6.1) # Image -------------------------------------------------- #subplot(234) diff --git a/examples/HydroTests/InteractingBlastWaves_1D/interactingBlastWaves.yml b/examples/HydroTests/InteractingBlastWaves_1D/interactingBlastWaves.yml index c4960dfa2c07b6b08cd6559b1de49f27b518bf94..aaad57dc0907cbe496ecb819d6df2a3805f7babf 100644 --- a/examples/HydroTests/InteractingBlastWaves_1D/interactingBlastWaves.yml +++ b/examples/HydroTests/InteractingBlastWaves_1D/interactingBlastWaves.yml @@ -10,7 +10,7 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 3.8e-2 # The end time of the simulation (in internal units). - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-10 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-5 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots diff --git a/examples/HydroTests/Noh_1D/noh.yml b/examples/HydroTests/Noh_1D/noh.yml index 58e13ddda8939c8fc5fa4360a498a87f1c5b189a..3a7e328df1da1477d34d56d25121cdd4e89c03a0 100644 --- a/examples/HydroTests/Noh_1D/noh.yml +++ b/examples/HydroTests/Noh_1D/noh.yml @@ -10,7 +10,7 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 0.6 # The end time of the simulation (in internal units). - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-10 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-3 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots @@ -33,4 +33,4 @@ InitialConditions: file_name: ./noh.hdf5 # The file to read periodic: 1 - \ No newline at end of file + diff --git a/examples/HydroTests/Noh_2D/noh.yml b/examples/HydroTests/Noh_2D/noh.yml index eaf991631854e9a9781f0fcee50d996f8af949cd..76ac8eb911faca76921370ee726ee8efa00000f3 100644 --- a/examples/HydroTests/Noh_2D/noh.yml +++ b/examples/HydroTests/Noh_2D/noh.yml @@ -10,7 +10,7 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 0.6 # The end time of the simulation (in internal units). - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-10 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-3 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots diff --git a/examples/HydroTests/SedovBlast_2D/sedov.yml b/examples/HydroTests/SedovBlast_2D/sedov.yml index b4252581d6eb3b2932a074e7545b2d308be51865..208e4ac72207140e055b3164ceaac04f7f521e4f 100644 --- a/examples/HydroTests/SedovBlast_2D/sedov.yml +++ b/examples/HydroTests/SedovBlast_2D/sedov.yml @@ -10,7 +10,7 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 5e-2 # The end time of the simulation (in internal units). - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-9 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-2 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots diff --git a/examples/HydroTests/SedovBlast_3D/plotSolution.py b/examples/HydroTests/SedovBlast_3D/plotSolution.py index ad34695d36f1bf8e8985b883200f17d6e38a70c9..b0f2e08441b3fa550e61602ba852228a04362fbc 100644 --- a/examples/HydroTests/SedovBlast_3D/plotSolution.py +++ b/examples/HydroTests/SedovBlast_3D/plotSolution.py @@ -24,7 +24,7 @@ # Parameters rho_0 = 1. # Background Density P_0 = 1.e-6 # Background Pressure -E_0 = 1. # Energy of the explosion +E_0 = 1.0 # Energy of the explosion gas_gamma = 5./3. # Gas polytropic index @@ -86,6 +86,18 @@ S = sim["/PartType0/Entropy"][:] P = sim["/PartType0/Pressure"][:] rho = sim["/PartType0/Density"][:] +try: + diffusion = sim["/PartType0/Diffusion"][:] + plot_diffusion = True +except: + plot_diffusion = False + +try: + viscosity = sim["/PartType0/Viscosity"][:] + plot_viscosity = True +except: + plot_viscosity = False + # Bin te data r_bin_edge = np.arange(0., 0.5, 0.01) r_bin = 0.5*(r_bin_edge[1:] + r_bin_edge[:-1]) @@ -105,6 +117,16 @@ P_sigma_bin = np.sqrt(P2_bin - P_bin**2) S_sigma_bin = np.sqrt(S2_bin - S_bin**2) u_sigma_bin = np.sqrt(u2_bin - u_bin**2) +if plot_diffusion: + alpha_diff_bin,_,_ = stats.binned_statistic(r, diffusion, statistic='mean', bins=r_bin_edge) + alpha2_diff_bin,_,_ = stats.binned_statistic(r, diffusion**2, statistic='mean', bins=r_bin_edge) + alpha_diff_sigma_bin = np.sqrt(alpha2_diff_bin - alpha_diff_bin**2) + +if plot_viscosity: + alpha_visc_bin,_,_ = stats.binned_statistic(r, viscosity, statistic='mean', bins=r_bin_edge) + alpha2_visc_bin,_,_ = stats.binned_statistic(r, viscosity**2, statistic='mean', bins=r_bin_edge) + alpha_visc_sigma_bin = np.sqrt(alpha2_visc_bin - alpha_visc_bin**2) + # Now, work our the solution.... @@ -274,14 +296,28 @@ ylim(-2, 22) # Entropy profile --------------------------------- subplot(235) -plot(r, S, '.', color='r', ms=0.5, alpha=0.2) -plot(r_s, s_s, '--', color='k', alpha=0.8, lw=1.2) -errorbar(r_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) xlabel("${\\rm{Radius}}~r$", labelpad=0) -ylabel("${\\rm{Entropy}}~S$", labelpad=0) -xlim(0, 1.3 * r_shock) -ylim(-5, 50) + +if plot_diffusion or plot_viscosity: + if plot_diffusion: + plot(r, diffusion, ".", color='r', ms=0.5, alpha=0.2) + errorbar(r_bin, alpha_diff_bin, yerr=alpha_diff_sigma_bin, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion") + + if plot_viscosity: + plot(r, viscosity, ".", color='g', ms=0.5, alpha=0.2) + errorbar(r_bin, alpha_visc_bin, yerr=alpha_visc_sigma_bin, fmt=".", ms=8.0, color='y', lw=1.2, label="Viscosity") + + ylabel("${\\rm{Rate~Coefficient}}~\\alpha$", labelpad=0) + legend() +else: + plot(r, S, '.', color='r', ms=0.5, alpha=0.2) + plot(r_s, s_s, '--', color='k', alpha=0.8, lw=1.2) + errorbar(r_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) + ylabel("${\\rm{Entropy}}~S$", labelpad=0) + ylim(-5, 50) + +xlim(0, 1.3 * r_shock) # Information ------------------------------------- subplot(236, frameon=False) diff --git a/examples/HydroTests/SedovBlast_3D/sedov.yml b/examples/HydroTests/SedovBlast_3D/sedov.yml index 19e8c72538a748304ca4da076458c9ae27dc8f46..00419ba94b262a1c94c0d3cd31acf70c949b9164 100644 --- a/examples/HydroTests/SedovBlast_3D/sedov.yml +++ b/examples/HydroTests/SedovBlast_3D/sedov.yml @@ -10,7 +10,7 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 5e-2 # The end time of the simulation (in internal units). - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-9 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-2 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots diff --git a/examples/HydroTests/SodShock_3D/plotSolution.py b/examples/HydroTests/SodShock_3D/plotSolution.py index 6da7193bcd3cdfb7c22a3fc6a14f91aea5cff5f7..69b2fe4887e986156ed01e0f4177d01ccbed6035 100644 --- a/examples/HydroTests/SodShock_3D/plotSolution.py +++ b/examples/HydroTests/SodShock_3D/plotSolution.py @@ -84,6 +84,18 @@ S = sim["/PartType0/Entropy"][:] P = sim["/PartType0/Pressure"][:] rho = sim["/PartType0/Density"][:] +try: + diffusion = sim["/PartType0/Diffusion"][:] + plot_diffusion = True +except: + plot_diffusion = False + +try: + viscosity = sim["/PartType0/Viscosity"][:] + plot_viscosity = True +except: + plot_viscosity = False + x_min = -1. x_max = 1. x += x_min @@ -108,6 +120,15 @@ P_sigma_bin = np.sqrt(P2_bin - P_bin**2) S_sigma_bin = np.sqrt(S2_bin - S_bin**2) u_sigma_bin = np.sqrt(u2_bin - u_bin**2) +if plot_diffusion: + alpha_diff_bin,_,_ = stats.binned_statistic(x, diffusion, statistic='mean', bins=x_bin_edge) + alpha2_diff_bin,_,_ = stats.binned_statistic(x, diffusion**2, statistic='mean', bins=x_bin_edge) + alpha_diff_sigma_bin = np.sqrt(alpha2_diff_bin - alpha_diff_bin**2) + +if plot_viscosity: + alpha_visc_bin,_,_ = stats.binned_statistic(x, viscosity, statistic='mean', bins=x_bin_edge) + alpha2_visc_bin,_,_ = stats.binned_statistic(x, viscosity**2, statistic='mean', bins=x_bin_edge) + alpha_visc_sigma_bin = np.sqrt(alpha2_visc_bin - alpha_visc_bin**2) # Analytic solution c_L = sqrt(gas_gamma * P_L / rho_L) # Speed of the rarefaction wave @@ -282,13 +303,26 @@ ylim(0.8, 2.2) # Entropy profile --------------------------------- subplot(235) -plot(x, S, '.', color='r', ms=0.5, alpha=0.2) -plot(x_s, s_s, '--', color='k', alpha=0.8, lw=1.2) -errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) -xlabel("${\\rm{Position}}~x$", labelpad=0) -ylabel("${\\rm{Entropy}}~S$", labelpad=0) xlim(-0.5, 0.5) -ylim(0.8, 3.8) +xlabel("${\\rm{Position}}~x$", labelpad=0) + +if plot_diffusion or plot_viscosity: + if plot_diffusion: + plot(x, diffusion * 100, ".", color='r', ms=0.5, alpha=0.2) + errorbar(x_bin, alpha_diff_bin * 100, yerr=alpha_diff_sigma_bin * 100, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion (100x)") + + if plot_viscosity: + plot(x, viscosity, ".", color='g', ms=0.5, alpha=0.2) + errorbar(x_bin, alpha_visc_bin, yerr=alpha_visc_sigma_bin, fmt=".", ms=8.0, color='y', lw=1.2, label="Viscosity") + + ylabel("${\\rm{Rate~Coefficient}}~\\alpha$", labelpad=0) + legend() +else: + plot(x, S, '.', color='r', ms=0.5, alpha=0.2) + plot(x_s, s_s, '--', color='k', alpha=0.8, lw=1.2) + errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) + ylabel("${\\rm{Entropy}}~S$", labelpad=0) + ylim(0.8, 3.8) # Information ------------------------------------- subplot(236, frameon=False) diff --git a/examples/HydroTests/UniformBox_3D/makeICbig.py b/examples/HydroTests/UniformBox_3D/makeICbig.py index bd5cf627fb535595b3abb224cbc8de50589f12cf..8841b601656d6f03684e81b4012597615485304f 100644 --- a/examples/HydroTests/UniformBox_3D/makeICbig.py +++ b/examples/HydroTests/UniformBox_3D/makeICbig.py @@ -45,7 +45,7 @@ internalEnergy = P / ((gamma - 1.)*rho) n_iterations = numPart / N remainder = numPart % N -print "Writing", numPart, "in", n_iterations, "iterations of size", N, "and a remainder of", remainder +print("Writing", numPart, "in", n_iterations, "iterations of size", N, "and a remainder of", remainder) #--------------------------------------------------- @@ -55,8 +55,8 @@ file = h5py.File(fileName, 'w') # Header grp = file.create_group("/Header") grp.attrs["BoxSize"] = boxSize -grp.attrs["NumPart_Total"] = [numPart % (long(1)<<32), 0, 0, 0, 0, 0] -grp.attrs["NumPart_Total_HighWord"] = [numPart / (long(1)<<32), 0, 0, 0, 0, 0] +grp.attrs["NumPart_Total"] = [numPart % (int(1)<<32), 0, 0, 0, 0, 0] +grp.attrs["NumPart_Total_HighWord"] = [numPart / (int(1)<<32), 0, 0, 0, 0, 0] grp.attrs["NumPart_ThisFile"] = [numPart, 0, 0, 0, 0, 0] grp.attrs["Time"] = 0.0 grp.attrs["NumFilesPerSnapshot"] = 1 @@ -120,7 +120,7 @@ for n in range(n_iterations): coords = zeros((1,3)) offset += N - print "Done", offset,"/", numPart, "(%.1f %%)"%(100*(float)(offset)/numPart) + print("Done", offset,"/", numPart, "(%.1f %%)"%(100*(float)(offset)/numPart)) # And now, the remainder v = zeros((remainder, 3)) @@ -150,7 +150,7 @@ coords[:,1] = y[:,0] * boxSize / L + boxSize / (2*L) coords[:,2] = x[:,0] * boxSize / L + boxSize / (2*L) ods_x[offset:offset+remainder,:] = coords -print "Done", offset+remainder,"/", numPart +print("Done", offset+remainder,"/", numPart) diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index 1e50c162d02e8c326f67978a7de73fda5c6aecd8..fddc9a62067d23e13b8c2229ad5d5e798600b4e0 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -122,59 +122,65 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( /* Nothing to do here? */ if (dt == 0.) return; - /* Current energy */ - const float u_old = hydro_get_physical_internal_energy(p, xp, cosmo); + /* Current energy (in internal units) */ + const float u_old_com = hydro_get_comoving_internal_energy(p, xp); - /* Current du_dt in physical coordinates (internal units) */ - const float hydro_du_dt = hydro_get_physical_internal_energy_dt(p, cosmo); + /* Y' = RHS of the comoving equation for du/dt that will be integrated + forward in time using dt_therm */ + const float hydro_du_dt_com = hydro_get_comoving_internal_energy_dt(p); /* Calculate cooling du_dt (in cgs units) */ const double cooling_du_dt_cgs = cooling_rate_cgs(cosmo, hydro_props, cooling, p); /* Convert to internal units */ - float cooling_du_dt = + const float cooling_du_dt_physical = cooling_du_dt_cgs * cooling->conv_factor_energy_rate_from_cgs; - /* Add cosmological term */ - cooling_du_dt *= cosmo->a * cosmo->a; + /* Add cosmological term to get Y_cooling' */ + const float cooling_du_dt = cooling_du_dt_physical * cosmo->a * cosmo->a / + cosmo->a_factor_internal_energy; - float total_du_dt = hydro_du_dt + cooling_du_dt; + /* Y_total' */ + float total_du_dt = hydro_du_dt_com + cooling_du_dt; /* We now need to check that we are not going to go below any of the limits */ - /* Limit imposed by the entropy floor */ - const float A_floor = entropy_floor(p, cosmo, floor_props); - const float rho = hydro_get_physical_density(p, cosmo); - const float u_floor = gas_internal_energy_from_entropy(rho, A_floor); + /* Limit imposed by the entropy floor (comoving) + * (Recall entropy is the same in physical and comoving frames) */ + const float A_floor_com = entropy_floor(p, cosmo, floor_props); + const float rho_com = hydro_get_comoving_density(p); + const float u_floor_com = + gas_internal_energy_from_entropy(rho_com, A_floor_com); /* Absolute minimum */ - const float u_minimal = hydro_props->minimal_internal_energy; + const float u_minimal_com = + hydro_props->minimal_internal_energy / cosmo->a_factor_internal_energy; /* Largest of both limits */ - const float u_limit = max(u_minimal, u_floor); + const float u_limit_com = max(u_minimal_com, u_floor_com); /* First, check whether we may end up below the minimal energy after * this step 1/2 kick + another 1/2 kick that could potentially be for * a time-step twice as big. We hence check for 1.5 delta_t. */ - if (u_old + total_du_dt * 1.5 * dt_therm < u_limit) { - total_du_dt = (u_limit - u_old) / (1.5f * dt_therm); + if (u_old_com + total_du_dt * 1.5 * dt_therm < u_limit_com) { + total_du_dt = (u_limit_com - u_old_com) / (1.5f * dt_therm); } /* Second, check whether the energy used in the prediction could get negative. * We need to check for the 1/2 dt kick followed by a full time-step drift * that could potentially be for a time-step twice as big. We hence check * for 2.5 delta_t but this time against 0 energy not the minimum */ - if (u_old + total_du_dt * 2.5 * dt_therm < 0.) { - total_du_dt = -u_old / ((2.5f + 0.0001f) * dt_therm); + if (u_old_com + total_du_dt * 2.5 * dt_therm < 0.) { + total_du_dt = -u_old_com / ((2.5f + 0.0001f) * dt_therm); } /* Update the internal energy time derivative */ - hydro_set_physical_internal_energy_dt(p, cosmo, total_du_dt); + hydro_set_comoving_internal_energy_dt(p, total_du_dt); /* Store the radiated energy (assuming dt will not change) */ xp->cooling_data.radiated_energy += - -hydro_get_mass(p) * (total_du_dt - hydro_du_dt) * dt_therm; + -hydro_get_mass(p) * cooling_du_dt_physical * dt; } /** @@ -208,8 +214,9 @@ __attribute__((always_inline)) INLINE static float cooling_timestep( cooling_rate_cgs(cosmo, hydro_props, cooling, p); /* Convert to internal units */ - const float cooling_du_dt = - cooling_du_dt_cgs * cooling->conv_factor_energy_rate_from_cgs; + const float cooling_du_dt = cooling_du_dt_cgs * + cooling->conv_factor_energy_rate_from_cgs / + cosmo->a_factor_internal_energy; /* If we are close to (or below) the limit, we ignore the condition */ if (u < 1.01f * hydro_props->minimal_internal_energy || cooling_du_dt == 0.f) @@ -270,7 +277,7 @@ INLINE static float cooling_get_temperature( const double mu_ionised = hydro_props->mu_ionised; /* Particle temperature */ - const double u = hydro_get_physical_internal_energy(p, xp, cosmo); + const double u = hydro_get_drifted_physical_internal_energy(p, cosmo); /* Temperature over mean molecular weight */ const double T_over_mu = hydro_gamma_minus_one * u * m_H / k_B; @@ -353,6 +360,9 @@ static INLINE void cooling_print_backend( "cm^3]", cooling->lambda_nH2_cgs); + message("Lambda/n_H^2=%g [internal units]", + cooling->lambda_nH2_cgs * cooling->conv_factor_energy_rate_from_cgs); + if (cooling->cooling_tstep_mult == FLT_MAX) message("Cooling function time-step size is unlimited"); else diff --git a/src/cooling/const_lambda/cooling_io.h b/src/cooling/const_lambda/cooling_io.h index 9437f0f94db41725d6715cf349843bf079137305..2e2ba799ab51a73c610701499ef61f1b398e42c5 100644 --- a/src/cooling/const_lambda/cooling_io.h +++ b/src/cooling/const_lambda/cooling_io.h @@ -76,7 +76,10 @@ __attribute__((always_inline)) INLINE static int cooling_write_particles( UNIT_CONV_TEMPERATURE, parts, xparts, convert_part_T); - return 1; + list[1] = io_make_output_field("RadiatedEnergy", FLOAT, 1, UNIT_CONV_ENERGY, + xparts, cooling_data.radiated_energy); + + return 2; } #endif /* SWIFT_COOLING_CONST_LAMBDA_IO_H */ diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 37d182889b703df9ea6d98b63a6daa5dc85274a8..0ac52165ec4b6dc5c193cf3d22d20458d2e643d3 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -218,6 +218,7 @@ hydro_get_comoving_soundspeed(const struct part *restrict p) { /* Compute the sound speed -- see theory section for justification */ /* IDEAL GAS ONLY -- P-U does not work with generic EoS. */ + const float square_rooted = sqrtf(hydro_gamma * p->pressure_bar / p->rho); return square_rooted; @@ -233,7 +234,7 @@ __attribute__((always_inline)) INLINE static float hydro_get_physical_soundspeed(const struct part *restrict p, const struct cosmology *cosmo) { - return cosmo->a_factor_sound_speed * p->force.soundspeed; + return cosmo->a_factor_sound_speed * hydro_get_comoving_soundspeed(p); } /** @@ -541,8 +542,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( p->density.rot_v[2] *= h_inv_dim_plus_one * a_inv2 * rho_inv; /* Finish calculation of the velocity divergence */ - p->viscosity.div_v *= - h_inv_dim_plus_one * rho_inv * a_inv2 + cosmo->H * hydro_dimension; + p->viscosity.div_v *= h_inv_dim_plus_one * rho_inv * a_inv2; + p->viscosity.div_v += cosmo->H * hydro_dimension; } /** @@ -693,18 +694,31 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Here we need to update the artificial viscosity */ - /* Timescale for decay */ - const float tau = - p->h / (2.f * p->viscosity.v_sig * hydro_props->viscosity.length); - /* Construct time differential of div.v implicitly */ - const float div_v_dt = + /* We use in this function that h is the radius of support */ + const float kernel_support_physical = p->h * cosmo->a * kernel_gamma; + const float v_sig_physical = p->viscosity.v_sig * cosmo->a_factor_sound_speed; + const float soundspeed_physical = hydro_get_physical_soundspeed(p, cosmo); + + const float sound_crossing_time_inverse = + soundspeed_physical / kernel_support_physical; + + /* Construct time differential of div.v implicitly following the ANARCHY spec + */ + + float div_v_dt = dt_alpha == 0.f ? 0.f : (p->viscosity.div_v - p->viscosity.div_v_previous_step) / dt_alpha; + /* Construct the source term for the AV; if shock detected this is _positive_ * as div_v_dt should be _negative_ before the shock hits */ - const float S = p->h * p->h * max(0.f, -1.f * div_v_dt); - const float v_sig_square = p->viscosity.v_sig * p->viscosity.v_sig; + const float S = kernel_support_physical * kernel_support_physical * + max(0.f, -1.f * div_v_dt); + /* 0.25 factor comes from our definition of v_sig (sum of soundspeeds rather + * than mean). */ + /* Note this is v_sig_physical squared, not comoving */ + const float v_sig_square = 0.25 * v_sig_physical * v_sig_physical; + /* Calculate the current appropriate value of the AV based on the above */ const float alpha_loc = hydro_props->viscosity.alpha_max * S / (v_sig_square + S); @@ -713,11 +727,11 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Reset the value of alpha to the appropriate value */ p->viscosity.alpha = alpha_loc; } else { - /* Integrate the alpha forward in time to decay back to alpha = 0 */ - const float alpha_dt = (alpha_loc - p->viscosity.alpha) / tau; - - /* Finally, we can update the actual value of the alpha */ - p->viscosity.alpha += alpha_dt * dt_alpha; + /* Integrate the alpha forward in time to decay back to alpha = alpha_loc */ + p->viscosity.alpha = + alpha_loc + (p->viscosity.alpha - alpha_loc) * + expf(-dt_alpha * sound_crossing_time_inverse * + hydro_props->viscosity.length); } if (p->viscosity.alpha < hydro_props->viscosity.alpha_min) { @@ -729,16 +743,21 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Now for the diffusive alpha */ + const float diffusion_timescale_physical_inverse = + v_sig_physical / kernel_support_physical; + const float sqrt_u = sqrtf(p->u); /* Calculate initial value of alpha dt before bounding */ - /* alpha_diff_dt is cosmology-less */ - /* Evolution term: following Schaller+ 2015 */ - float alpha_diff_dt = - hydro_props->diffusion.beta * p->h * p->diffusion.laplace_u / sqrt_u; + /* Evolution term: following Schaller+ 2015. This is made up of several + cosmology factors: physical h, sound speed from u / sqrt(u), and the + 1 / a^2 coming from the laplace operator. */ + float alpha_diff_dt = hydro_props->diffusion.beta * kernel_support_physical * + p->diffusion.laplace_u * cosmo->a_factor_sound_speed / + (sqrt_u * cosmo->a * cosmo->a); /* Decay term: not documented in Schaller+ 2015 but was present * in the original EAGLE code and in Schaye+ 2015 */ - alpha_diff_dt -= - (p->diffusion.alpha - hydro_props->diffusion.alpha_min) / tau; + alpha_diff_dt -= (p->diffusion.alpha - hydro_props->diffusion.alpha_min) * + diffusion_timescale_physical_inverse; float new_diffusion_alpha = p->diffusion.alpha; new_diffusion_alpha += alpha_diff_dt * dt_alpha; diff --git a/src/hydro/AnarchyPU/hydro_iact.h b/src/hydro/AnarchyPU/hydro_iact.h index c214db3b018e00b7f3881fb301b55d6cf49a1f43..d091ebebcf4f165db006ca58667e943ddbaf8599 100644 --- a/src/hydro/AnarchyPU/hydro_iact.h +++ b/src/hydro/AnarchyPU/hydro_iact.h @@ -200,14 +200,28 @@ __attribute__((always_inline)) INLINE static void runner_iact_gradient( /* We need to construct the maximal signal velocity between our particle * and all of it's neighbours */ - const float dv_dx = (pi->v[0] - pj->v[0]) * dx[0] + - (pi->v[1] - pj->v[1]) * dx[1] + - (pi->v[2] - pj->v[2]) * dx[2]; + const float r = sqrtf(r2); + const float r_inv = 1.f / r; + const float ci = pi->force.soundspeed; + const float cj = pj->force.soundspeed; + + /* Cosmology terms for the signal velocity */ + const float fac_mu = pow_three_gamma_minus_five_over_two(a); + const float a2_Hubble = a * a * H; + + const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] + + (pi->v[1] - pj->v[1]) * dx[1] + + (pi->v[2] - pj->v[2]) * dx[2]; - const float dv_dx_factor = min(0, const_viscosity_beta * dv_dx); + /* Add Hubble flow */ - const float new_v_sig = - pi->force.soundspeed + pj->force.soundspeed - dv_dx_factor; + const float dvdr_Hubble = dvdr + a2_Hubble * r2; + /* Are the particles moving towards each others ? */ + const float omega_ij = min(dvdr_Hubble, 0.f); + const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */ + + /* Signal velocity */ + const float new_v_sig = ci + cj - const_viscosity_beta * mu_ij; /* Update if we need to */ pi->viscosity.v_sig = max(pi->viscosity.v_sig, new_v_sig); @@ -217,14 +231,13 @@ __attribute__((always_inline)) INLINE static void runner_iact_gradient( /* Need to get some kernel values F_ij = wi_dx */ float wi, wi_dx, wj, wj_dx; - const float r = sqrtf(r2); const float ui = r / hi; const float uj = r / hj; kernel_deval(ui, &wi, &wi_dx); kernel_deval(uj, &wj, &wj_dx); - const float delta_u_factor = (pi->u - pj->u) / r; + const float delta_u_factor = (pi->u - pj->u) * r_inv; pi->diffusion.laplace_u += pj->mass * delta_u_factor * wi_dx / pj->rho; pj->diffusion.laplace_u -= pi->mass * delta_u_factor * wj_dx / pi->rho; } @@ -253,14 +266,28 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_gradient( /* We need to construct the maximal signal velocity between our particle * and all of it's neighbours */ - const float dv_dx = (pi->v[0] - pj->v[0]) * dx[0] + - (pi->v[1] - pj->v[1]) * dx[1] + - (pi->v[2] - pj->v[2]) * dx[2]; + const float r = sqrtf(r2); + const float r_inv = 1.f / r; + const float ci = pi->force.soundspeed; + const float cj = pj->force.soundspeed; + + /* Cosmology terms for the signal velocity */ + const float fac_mu = pow_three_gamma_minus_five_over_two(a); + const float a2_Hubble = a * a * H; + + const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] + + (pi->v[1] - pj->v[1]) * dx[1] + + (pi->v[2] - pj->v[2]) * dx[2]; - const float dv_dx_factor = min(0, const_viscosity_beta * dv_dx); + /* Add Hubble flow */ - const float new_v_sig = - pi->force.soundspeed + pj->force.soundspeed - dv_dx_factor; + const float dvdr_Hubble = dvdr + a2_Hubble * r2; + /* Are the particles moving towards each others ? */ + const float omega_ij = min(dvdr_Hubble, 0.f); + const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */ + + /* Signal velocity */ + const float new_v_sig = ci + cj - const_viscosity_beta * mu_ij; /* Update if we need to */ pi->viscosity.v_sig = max(pi->viscosity.v_sig, new_v_sig); @@ -269,12 +296,11 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_gradient( /* Need to get some kernel values F_ij = wi_dx */ float wi, wi_dx; - const float r = sqrtf(r2); const float ui = r / hi; kernel_deval(ui, &wi, &wi_dx); - const float delta_u_factor = (pi->u - pj->u) / r; + const float delta_u_factor = (pi->u - pj->u) * r_inv; pi->diffusion.laplace_u += pj->mass * delta_u_factor * wi_dx / pj->rho; } @@ -343,7 +369,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */ /* Compute sound speeds and signal velocity */ - const float v_sig = 0.5 * (pi->viscosity.v_sig + pj->viscosity.v_sig); + const float v_sig = 0.5f * (pi->viscosity.v_sig + pj->viscosity.v_sig); /* Balsara term */ const float balsara_i = pi->force.balsara; @@ -390,7 +416,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( /* Diffusion term */ const float v_diff = max(pi->force.soundspeed + pj->force.soundspeed + dvdr_Hubble, 0.f); - const float alpha_diff = 0.5 * (pi->diffusion.alpha + pj->diffusion.alpha); + const float alpha_diff = 0.5f * (pi->diffusion.alpha + pj->diffusion.alpha); /* wi_dx + wj_dx / 2 is F_ij */ const float diff_du_term = alpha_diff * fac_mu * v_diff * (pi->u - pj->u) * (wi_dr + wj_dr) / rho_ij; @@ -474,7 +500,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */ /* Compute sound speeds and signal velocity */ - const float v_sig = 0.5 * (pi->viscosity.v_sig + pj->viscosity.v_sig); + const float v_sig = 0.5f * (pi->viscosity.v_sig + pj->viscosity.v_sig); /* Balsara term */ const float balsara_i = pi->force.balsara; @@ -514,7 +540,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( /* Diffusion term */ const float v_diff = max(pi->force.soundspeed + pj->force.soundspeed + dvdr_Hubble, 0.f); - const float alpha_diff = 0.5 * (pi->diffusion.alpha + pj->diffusion.alpha); + const float alpha_diff = 0.5f * (pi->diffusion.alpha + pj->diffusion.alpha); /* wi_dx + wj_dx / 2 is F_ij */ const float diff_du_term = alpha_diff * fac_mu * v_diff * (pi->u - pj->u) * (wi_dr + wj_dr) / rho_ij; diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index bcef2480810c807d61a6545f04fca6144f90e8fe..f05e3229a03f18115aa0e60ba5fee94bc39c5b9e 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -562,7 +562,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( p->density.rot_v[2] * p->density.rot_v[2]); /* Compute the norm of div v including the Hubble flow term */ - const float div_physical_v = p->density.div_v + 3.f * cosmo->H; + const float div_physical_v = p->density.div_v + hydro_dimension * cosmo->H; const float abs_div_physical_v = fabsf(div_physical_v); /* Compute the pressure */ diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index 1d5d25f734acae72490ae42552abf65983463c07..e2fd0069524de32c49cbc3cb46553b18928d14bf 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -561,7 +561,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( p->density.rot_v[2] * p->density.rot_v[2]); /* Compute the norm of div v including the Hubble flow term */ - const float div_physical_v = p->density.div_v + 3.f * cosmo->H; + const float div_physical_v = p->density.div_v + hydro_dimension * cosmo->H; const float abs_div_physical_v = fabsf(div_physical_v); /* Compute the pressure */ diff --git a/src/hydro/PressureEnergy/hydro.h b/src/hydro/PressureEnergy/hydro.h index 0e53b5f2ea12462fb1a618cda44934d113f655dd..3fe3c805fd4df4b495b102f9061b1e0a507e84e9 100644 --- a/src/hydro/PressureEnergy/hydro.h +++ b/src/hydro/PressureEnergy/hydro.h @@ -530,8 +530,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( /* Finish calculation of the velocity divergence, including hubble flow term */ - p->density.div_v *= - h_inv_dim_plus_one * rho_inv * a_inv2 + cosmo->H * hydro_dimension; + p->density.div_v *= h_inv_dim_plus_one * rho_inv * a_inv2; + p->density.div_v += cosmo->H * hydro_dimension; } /** diff --git a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h index 9f981569e80021774cebaf11066ebdac2afc6f94..be6a789ebdcd664a99a95b83f70167da04bd7534 100644 --- a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h +++ b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h @@ -526,8 +526,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( p->density.rot_v[2] *= h_inv_dim_plus_one * a_inv2 * rho_inv; /* Finish calculation of the velocity divergence */ - p->density.div_v *= - h_inv_dim_plus_one * rho_inv * a_inv2 + cosmo->H * hydro_dimension; + p->density.div_v *= h_inv_dim_plus_one * rho_inv * a_inv2; + p->density.div_v += cosmo->H * hydro_dimension; } /** @@ -614,7 +614,14 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Artificial viscosity updates */ - const float inverse_tau = hydro_props->viscosity.length * soundspeed * h_inv; + /* TODO: Actually work out why this cosmology factor is correct + * and update the SPH / cosmology theory documents. */ + + /* We divide by a^2 here to make this transform under cosmology the + * same as the velocity (which in SWIFT has an extra 1/a^2 factor. + * See the cosmology theory documents for more information. */ + const float inverse_tau = + (hydro_props->viscosity.length * cosmo->a2_inv) * soundspeed * h_inv; const float source_term = -1.f * min(p->density.div_v, 0.f); /* Compute da/dt */ diff --git a/src/hydro_properties.c b/src/hydro_properties.c index ff578aec139ad06cb80279d8d827a41975f9773f..eb506839c859f561756fdc77072a915ff3a383aa 100644 --- a/src/hydro_properties.c +++ b/src/hydro_properties.c @@ -49,12 +49,15 @@ #ifdef ANARCHY_PU_SPH /* This nasty #ifdef is only temporary until we separate the viscosity * and hydro components. If it is not removed by July 2019, shout at JB. */ +#undef hydro_props_default_viscosity_alpha +#define hydro_props_default_viscosity_alpha \ + 0.1f /* Use a very low initial AV paramater for hydrodynamics tests */ #define hydro_props_default_viscosity_alpha_min \ - 0.01f /* values taken from Schaller+ 2015 */ + 0.0f /* values NOT the same as Schaller+ 2015 */ #define hydro_props_default_viscosity_alpha_max \ 2.0f /* values taken from Schaller+ 2015 */ #define hydro_props_default_viscosity_length \ - 0.01f /* values taken from Schaller+ 2015 */ + 0.25f /* values taken from Schaller+ 2015 */ #else #define hydro_props_default_viscosity_alpha_min \ 0.1f /* values taken from (price,2004), not used in legacy gadget mode */ diff --git a/src/runner.c b/src/runner.c index 979bdae38437129c62487e25895175db2095df70..8ac77172e1433ec0df875b0f2ed9644197f32db0 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1352,7 +1352,7 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c, int timer) { struct xpart *restrict xparts = c->hydro.xparts; const int count = c->hydro.count; const struct engine *e = r->e; - const integertime_t ti_end = e->ti_current; + const integertime_t ti_current = e->ti_current; const int with_cosmology = (e->policy & engine_policy_cosmology); const double time_base = e->time_base; const struct cosmology *cosmo = e->cosmology; @@ -1387,9 +1387,14 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c, int timer) { * This is the physical time between the start and end of the time-step * without any scale-factor powers. */ double dt_alpha; + if (with_cosmology) { const integertime_t ti_step = get_integer_timestep(p->time_bin); - dt_alpha = cosmology_get_delta_time(cosmo, ti_end - ti_step, ti_end); + const integertime_t ti_begin = + get_integer_time_begin(ti_current - 1, p->time_bin); + + dt_alpha = + cosmology_get_delta_time(cosmo, ti_begin, ti_begin + ti_step); } else { dt_alpha = get_timestep(p->time_bin, time_base); } @@ -1568,13 +1573,16 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { * artificial viscosity and thermal conduction terms) */ const int with_cosmology = (e->policy & engine_policy_cosmology); const double time_base = e->time_base; - const integertime_t ti_end = e->ti_current; + const integertime_t ti_current = e->ti_current; double dt_alpha; if (with_cosmology) { const integertime_t ti_step = get_integer_timestep(p->time_bin); + const integertime_t ti_begin = + get_integer_time_begin(ti_current - 1, p->time_bin); + dt_alpha = - cosmology_get_delta_time(cosmo, ti_end - ti_step, ti_end); + cosmology_get_delta_time(cosmo, ti_begin, ti_begin + ti_step); } else { dt_alpha = get_timestep(p->time_bin, time_base); } @@ -1712,13 +1720,17 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { * the evolution of alpha factors (i.e. those involved in the artificial * viscosity and thermal conduction terms) */ const int with_cosmology = (e->policy & engine_policy_cosmology); - const integertime_t ti_end = e->ti_current; const double time_base = e->time_base; + const integertime_t ti_current = e->ti_current; double dt_alpha; if (with_cosmology) { const integertime_t ti_step = get_integer_timestep(p->time_bin); - dt_alpha = cosmology_get_delta_time(cosmo, ti_end - ti_step, ti_end); + const integertime_t ti_begin = + get_integer_time_begin(ti_current - 1, p->time_bin); + + dt_alpha = + cosmology_get_delta_time(cosmo, ti_begin, ti_begin + ti_step); } else { dt_alpha = get_timestep(p->time_bin, time_base); }