diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..542c97e89adce40066f0b9a96cc8be9746640d65 --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +--- +Language: Cpp +BasedOnStyle: Google +KeepEmptyLinesAtTheStartOfBlocks: true +... diff --git a/INSTALL.swift b/INSTALL.swift index c18142c1a62c7c8a011ead2ee8d0d869c9e072ec..a4a2a9208c9443aacc796c87dfe1b96ee88fbb34 100644 --- a/INSTALL.swift +++ b/INSTALL.swift @@ -30,7 +30,7 @@ or: ./configure CC=icc to use an Intel compiler. The main "programs" can be found in the "examples/" -directory. +directory. See README for run parameters. SWIFT has been successfully built and tested with the following compilers: @@ -105,3 +105,14 @@ among the different cores on each computing node. DOXYGEN: the doxygen library is required to create the SWIFT API documentation. + + + + SWIFT Coding style + ================== + +The SWIFT source code is using a variation of the 'Google' style. The +script 'format.sh' in the root directory applies the clang-format-3.8 +tool with our style choices to all the SWIFT C source file. Please +apply the formatting script to the files before submitting a merge +request. diff --git a/Makefile.am b/Makefile.am index 9d4f6371b7aa37a1750c5fb8dbed17f9ff48442e..fb4eb5f6d6b63a7d0e034e0a3202ac61066e6e25 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,6 @@ - # This file is part of SWIFT. -# Copyright (c) 2012 pedro.gonnet@durham.ac.uk. -# 2015 matthieu.schaller@durham.ac.uk. +# Copyright (c) 2012 pedro.gonnet@durham.ac.uk +# 2015 matthieu.schaller@durham.ac.uk # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -23,4 +22,4 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src examples doc tests # Non-standard files that should be part of the distribution. -EXTRA_DIST = INSTALL.swift +EXTRA_DIST = INSTALL.swift .clang-format format.sh diff --git a/README b/README index 59c362415a9199d08fb6dfbb1ed044c66e647254..a010c4595a6e3a113879659390b373553c6e07d3 100644 --- a/README +++ b/README @@ -14,6 +14,7 @@ See INSTALL.swift for install instructions. Usage: swift [OPTION] PARAMFILE Valid options are: + -a Pin runners using processor affinity -c Run with cosmological time integration -d Dry run. Read the parameter file, allocate memory but does not read the particles from ICs and exit before the start of time integration. diff --git a/configure.ac b/configure.ac index 59eea9c4e55d5aa22fd5a2f41e7f9e0a97ad9571..497107121753f212dd8b07f5a8e8eed7acdf82b5 100644 --- a/configure.ac +++ b/configure.ac @@ -329,7 +329,7 @@ fi AM_CONDITIONAL([HAVEPARALLELHDF5],[test "$have_parallel_hdf5" = "yes"]) # Check for setaffinity. -AC_CHECK_FUNC(pthread_setaffinity_np, AC_DEFINE([HAVE_SETAFFINITY],[true], +AC_CHECK_FUNC(pthread_setaffinity_np, AC_DEFINE([HAVE_SETAFFINITY],[1], [Defined if pthread_setaffinity_np exists.]) ) AM_CONDITIONAL(HAVESETAFFINITY, [test "$ac_cv_func_pthread_setaffinity_np" = "yes"]) diff --git a/examples/CosmoVolume/cosmoVolume.yml b/examples/CosmoVolume/cosmoVolume.yml index 6075ad99799ddb671e34a5b590713e8441be56f6..45d32ae081823374d523a6105b196a4e1e7aa3c6 100644 --- a/examples/CosmoVolume/cosmoVolume.yml +++ b/examples/CosmoVolume/cosmoVolume.yml @@ -1,4 +1,3 @@ - # Define the system of units to use internally. InternalUnitSystem: UnitMass_in_cgs: 1 # Grams @@ -17,9 +16,9 @@ Scheduler: # Parameters governing the time integration TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). - time_end: 1. # The end time of the simulation (in internal units). + time_end: 1e-4 # The end time of the simulation (in internal units). dt_min: 1e-6 # 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). + dt_max: 1e-4 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots Snapshots: @@ -32,6 +31,10 @@ Snapshots: UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin +# Parameters governing the conserved quantities statistics +Statistics: + delta_time: 1e-2 # Time between statistics output + # 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). diff --git a/examples/ExternalPointMass/externalPointMass.yml b/examples/ExternalPointMass/externalPointMass.yml index 6d05cb5b43c541490432c8f283b662c9d7c8d184..cfc6f0ae6d15a50471900e0bd09113e942fc116d 100644 --- a/examples/ExternalPointMass/externalPointMass.yml +++ b/examples/ExternalPointMass/externalPointMass.yml @@ -1,4 +1,3 @@ - # Define the system of units to use internally. InternalUnitSystem: UnitMass_in_cgs: 1.9885e33 # Grams @@ -32,6 +31,10 @@ Snapshots: UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin +# Parameters governing the conserved quantities statistics +Statistics: + delta_time: 1e-2 # Time between statistics output + # 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). diff --git a/examples/SedovBlast/sedov.yml b/examples/SedovBlast/sedov.yml index b5ad8d855535e70133464fa6a117db37a2c9fb8b..1f491c248ffbd590dda5b5dcdf86b3eca27c8ce7 100644 --- a/examples/SedovBlast/sedov.yml +++ b/examples/SedovBlast/sedov.yml @@ -1,4 +1,3 @@ - # Define the system of units to use internally. InternalUnitSystem: UnitMass_in_cgs: 1 # Grams @@ -32,6 +31,10 @@ Snapshots: UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin +# Parameters governing the conserved quantities statistics +Statistics: + delta_time: 1e-3 # Time between statistics output + # 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). diff --git a/examples/SodShock/sodShock.yml b/examples/SodShock/sodShock.yml index 7bb1895c15c80c6a4e54248d1d2bf85dea278ce1..d61c593f10387ad1a6bfc9cbbe9e89f05f84c52c 100644 --- a/examples/SodShock/sodShock.yml +++ b/examples/SodShock/sodShock.yml @@ -1,4 +1,3 @@ - # Define the system of units to use internally. InternalUnitSystem: UnitMass_in_cgs: 1 # Grams @@ -32,6 +31,10 @@ Snapshots: UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin +# Parameters governing the conserved quantities statistics +Statistics: + delta_time: 1e-2 # Time between statistics output + # 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). diff --git a/examples/UniformBox/uniformBox.yml b/examples/UniformBox/uniformBox.yml index ce989d22ad8a2310ef86303e1b7b6788fdcc427f..15d956a5d752262db91208f689005a7dc85f30d5 100644 --- a/examples/UniformBox/uniformBox.yml +++ b/examples/UniformBox/uniformBox.yml @@ -1,4 +1,3 @@ - # Define the system of units to use internally. InternalUnitSystem: UnitMass_in_cgs: 1 # Grams @@ -32,6 +31,10 @@ Snapshots: UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin +# Parameters governing the conserved quantities statistics +Statistics: + delta_time: 1e-2 # Time between statistics output + # 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). diff --git a/examples/main.c b/examples/main.c index 19d2d7a7871200ba6e4902d5918a59511bf32b47..9f371d64dde9c66f118477beb145f426946fc9d9 100644 --- a/examples/main.c +++ b/examples/main.c @@ -27,10 +27,10 @@ /* Some standard headers. */ #include <fenv.h> -#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> /* MPI headers. */ #ifdef WITH_MPI @@ -52,6 +52,7 @@ void print_help_message() { printf("\nUsage: swift [OPTION] PARAMFILE\n\n"); printf("Valid options are:\n"); + printf(" %2s %8s %s\n", "-a", "", "Pin runners using processor affinity"); printf(" %2s %8s %s\n", "-c", "", "Run with cosmological time integration"); printf( " %2s %8s %s\n", "-d", "", @@ -88,6 +89,7 @@ void print_help_message() { * @brief Main routine that loads a few particles and generates some output. * */ + int main(int argc, char *argv[]) { struct clocks_time tic, toc; @@ -121,24 +123,16 @@ int main(int argc, char *argv[]) { fflush(stdout); #endif +/* Let's pin the main thread */ #if defined(HAVE_SETAFFINITY) && defined(HAVE_LIBNUMA) && defined(_GNU_SOURCE) - if ((ENGINE_POLICY) & engine_policy_setaffinity) { - /* Ensure the NUMA node on which we initialise (first touch) everything - * doesn't change before engine_init allocates NUMA-local workers. - * Otherwise, we may be scheduled elsewhere between the two times. - */ - cpu_set_t affinity; - CPU_ZERO(&affinity); - CPU_SET(sched_getcpu(), &affinity); - if (sched_setaffinity(0, sizeof(cpu_set_t), &affinity) != 0) { - error("failed to set entry thread's affinity"); - } - } + if (((ENGINE_POLICY)&engine_policy_setaffinity) == engine_policy_setaffinity) + engine_pin(); #endif /* Welcome to SWIFT, you made the right choice */ if (myrank == 0) greetings(); + int with_aff = 0; int dry_run = 0; int dump_tasks = 0; int with_cosmology = 0; @@ -153,7 +147,10 @@ int main(int argc, char *argv[]) { /* Parse the parameters */ int c; - while ((c = getopt(argc, argv, "cdef:gGhst:v:y:")) != -1) switch (c) { + while ((c = getopt(argc, argv, "acdef:gGhst:v:y:")) != -1) switch (c) { + case 'a': + with_aff = 1; + break; case 'c': with_cosmology = 1; break; @@ -393,6 +390,7 @@ int main(int argc, char *argv[]) { message("%zi parts in %i cells.", s.nr_parts, s.tot_cells); message("%zi gparts in %i cells.", s.nr_gparts, s.tot_cells); message("maximum depth is %d.", s.maxdepth); + fflush(stdout); } /* Verify that each particle is in it's proper cell. */ @@ -419,8 +417,9 @@ int main(int argc, char *argv[]) { /* Initialize the engine with the space and policies. */ if (myrank == 0) clocks_gettime(&tic); struct engine e; - engine_init(&e, &s, params, nr_nodes, myrank, nr_threads, engine_policies, - talking, &prog_const, &hydro_properties, &potential); + engine_init(&e, &s, params, nr_nodes, myrank, nr_threads, with_aff, + engine_policies, talking, &prog_const, &hydro_properties, + &potential); if (myrank == 0) { clocks_gettime(&toc); message("engine_init took %.3f %s.", clocks_diff(&tic, &toc), @@ -431,10 +430,6 @@ int main(int argc, char *argv[]) { /* Write the state of the system before starting time integration. */ if (!dry_run) engine_dump_snapshot(&e); - /* Now that everything is ready, no need for the parameters any more */ - free(params); - params = NULL; - /* Init the runner history. */ #ifdef HIST for (k = 0; k < runner_hist_N; k++) runner_hist_bins[k] = 0; @@ -521,19 +516,20 @@ int main(int argc, char *argv[]) { int count = 0; for (int l = 0; l < e.sched.nr_tasks; l++) if (!e.sched.tasks[l].skip && !e.sched.tasks[l].implicit) { - fprintf(file_thread, " %03i %i %i %i %i %lli %lli %i %i %i %i %i\n", - myrank, e.sched.tasks[l].last_rid, e.sched.tasks[l].type, - e.sched.tasks[l].subtype, (e.sched.tasks[l].cj == NULL), - e.sched.tasks[l].tic, e.sched.tasks[l].toc, - (e.sched.tasks[l].ci != NULL) ? e.sched.tasks[l].ci->count - : 0, - (e.sched.tasks[l].cj != NULL) ? e.sched.tasks[l].cj->count - : 0, - (e.sched.tasks[l].ci != NULL) ? e.sched.tasks[l].ci->gcount - : 0, - (e.sched.tasks[l].cj != NULL) ? e.sched.tasks[l].cj->gcount - : 0, - e.sched.tasks[l].flags); + fprintf( + file_thread, " %03i %i %i %i %i %lli %lli %i %i %i %i %i\n", + myrank, e.sched.tasks[l].last_rid, e.sched.tasks[l].type, + e.sched.tasks[l].subtype, (e.sched.tasks[l].cj == NULL), + e.sched.tasks[l].tic, e.sched.tasks[l].toc, + (e.sched.tasks[l].ci != NULL) ? e.sched.tasks[l].ci->count + : 0, + (e.sched.tasks[l].cj != NULL) ? e.sched.tasks[l].cj->count + : 0, + (e.sched.tasks[l].ci != NULL) ? e.sched.tasks[l].ci->gcount + : 0, + (e.sched.tasks[l].cj != NULL) ? e.sched.tasks[l].cj->gcount + : 0, + e.sched.tasks[l].flags); fflush(stdout); count++; } @@ -552,8 +548,8 @@ int main(int argc, char *argv[]) { FILE *file_thread; file_thread = fopen(dumpfile, "w"); /* Add some information to help with the plots */ - fprintf(file_thread, " %i %i %i %i %lli %lli %i %i %i %lli\n", -2, -1, -1, 1, - e.tic_step, e.toc_step, 0, 0, 0, cpufreq); + fprintf(file_thread, " %i %i %i %i %lli %lli %i %i %i %lli\n", -2, -1, -1, + 1, e.tic_step, e.toc_step, 0, 0, 0, cpufreq); for (int l = 0; l < e.sched.nr_tasks; l++) if (!e.sched.tasks[l].skip && !e.sched.tasks[l].implicit) fprintf( diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index 761e2f67c16766bc341b2bcb47f40ebbc4ea30ad..b3b9b52ad73fad2bde9b40b983f88acc3e985fbb 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -1,4 +1,3 @@ - # Define the system of units to use internally. InternalUnitSystem: UnitMass_in_cgs: 1 # Grams @@ -32,6 +31,10 @@ Snapshots: UnitCurrent_in_cgs: 1 # Unit system for the outputs (Amperes) UnitTemp_in_cgs: 1 # Unit system for the outputs (Kelvin) +# Parameters governing the conserved quantities statistics +Statistics: + delta_time: 1e-2 # Time between statistics output + # 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). diff --git a/examples/plot_tasks.py b/examples/plot_tasks.py index ffabdf06f9324fba35770e7fbba4cfadc8add770..e070bdb565d6d8305b7974137292910dd720afe2 100755 --- a/examples/plot_tasks.py +++ b/examples/plot_tasks.py @@ -56,8 +56,8 @@ pl.rcParams.update(PLOT_PARAMS) # Tasks and subtypes. Indexed as in tasks.h. TASKTYPES = ["none", "sort", "self", "pair", "sub", "init", "ghost", "drift", - "kick", "send", "recv", "grav_pp", "grav_mm", "grav_up", - "grav_down", "grav_external", "part_sort", "gpart_sort", + "kick", "kick_fixdt", "send", "recv", "grav_pp", "grav_mm", + "grav_up", "grav_down", "grav_external", "part_sort", "gpart_sort", "split_cell", "rewait", "count"] TASKCOLOURS = {"none": "black", @@ -69,6 +69,7 @@ TASKCOLOURS = {"none": "black", "ghost": "cyan", "drift": "maroon", "kick": "green", + "kick_fixdt": "green", "send": "yellow", "recv": "magenta", "grav_pp": "mediumorchid", diff --git a/examples/plot_tasks_MPI.py b/examples/plot_tasks_MPI.py index cf591028b6dc3f724847b52c9efac4355d27f87e..44705a0164034f8a22f1f3aa860a64d3e7656d2e 100755 --- a/examples/plot_tasks_MPI.py +++ b/examples/plot_tasks_MPI.py @@ -62,8 +62,8 @@ pl.rcParams.update(PLOT_PARAMS) # Tasks and subtypes. Indexed as in tasks.h. TASKTYPES = ["none", "sort", "self", "pair", "sub", "init", "ghost", "drift", - "kick", "send", "recv", "grav_pp", "grav_mm", "grav_up", - "grav_down", "grav_external", "part_sort", "gpart_sort", + "kick", "kick_fixdt", "send", "recv", "grav_pp", "grav_mm", + "grav_up", "grav_down", "grav_external", "part_sort", "gpart_sort", "split_cell", "rewait", "count"] TASKCOLOURS = {"none": "black", @@ -75,6 +75,7 @@ TASKCOLOURS = {"none": "black", "ghost": "cyan", "drift": "maroon", "kick": "green", + "kick_fixdt": "green", "send": "yellow", "recv": "magenta", "grav_pp": "mediumorchid", diff --git a/format.sh b/format.sh new file mode 100755 index 0000000000000000000000000000000000000000..5bf78c5bb663d5cf22178bff868912a059c5c4fe --- /dev/null +++ b/format.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +clang-format-3.8 -style=file -i src/*.[ch] src/*/*.[ch] src/*/*/*.[ch] examples/main.c tests/*.[ch] diff --git a/src/Makefile.am b/src/Makefile.am index 322a4823527f078da9142229c6e2b8d100379610..6d96fd01de5b4be002ad5dc03c65d5145ada7177 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,7 +48,8 @@ AM_SOURCES = space.c runner.c queue.c task.c cell.c engine.c \ # Include files for distribution, not installation. nobase_noinst_HEADERS = approx_math.h atomic.h cycle.h error.h inline.h kernel_hydro.h kernel_gravity.h \ - vector.h runner_doiact.h runner_doiact_grav.h units.h intrinsics.h minmax.h \ + vector.h runner_doiact.h runner_doiact_grav.h units.h intrinsics.h minmax.h kick.h \ + timestep.h drift.h \ gravity.h gravity_io.h \ gravity/Default/gravity.h gravity/Default/gravity_iact.h gravity/Default/gravity_io.h \ gravity/Default/gravity_debug.h gravity/Default/gravity_part.h \ diff --git a/src/cell.c b/src/cell.c index 29072173b060a936fe6f4f43c091581d522985b3..97a67583a7872999d7b7e7c5a0eb9787c83b4bd3 100644 --- a/src/cell.c +++ b/src/cell.c @@ -50,8 +50,8 @@ #include "atomic.h" #include "error.h" #include "gravity.h" -#include "hydro_properties.h" #include "hydro.h" +#include "hydro_properties.h" #include "space.h" #include "timers.h" diff --git a/src/cell.h b/src/cell.h index a69a1a74648d76aeb13126d37a3c1265397dc2bf..65665c9dcfcd652cc688f652008044d618b10790 100644 --- a/src/cell.h +++ b/src/cell.h @@ -136,13 +136,13 @@ struct cell { int hold, ghold; /* Spin lock for various uses. */ - lock_type lock, glock; + swift_lock_type lock, glock; /* ID of the previous owner, e.g. runner. */ int owner; /* Momentum of particles in cell. */ - float mom[3], ang[3]; + double mom[3], ang_mom[3]; /* Mass, potential, internal and kinetic energy of particles in this cell. */ double mass, e_pot, e_int, e_kin; diff --git a/src/common_io.c b/src/common_io.c index 143c1ca94160f2a43c40aa44384803ce721e4dbf..4399c83f7ebd2bb5355b7df9cc1fdecd301e36aa 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -147,8 +147,8 @@ void readAttribute(hid_t grp, char* name, enum DATA_TYPE type, void* data) { * * Calls #error() if an error occurs. */ -void writeAttribute(hid_t grp, char* name, enum DATA_TYPE type, void* data, - int num) { +void writeAttribute(hid_t grp, const char* name, enum DATA_TYPE type, + void* data, int num) { hid_t h_space = 0, h_attr = 0, h_err = 0; hsize_t dim[1] = {num}; @@ -186,7 +186,8 @@ void writeAttribute(hid_t grp, char* name, enum DATA_TYPE type, void* data, * * Calls #error() if an error occurs. */ -void writeStringAttribute(hid_t grp, char* name, const char* str, int length) { +void writeStringAttribute(hid_t grp, const char* name, const char* str, + int length) { hid_t h_space = 0, h_attr = 0, h_err = 0, h_type = 0; h_space = H5Screate(H5S_SCALAR); @@ -225,7 +226,7 @@ void writeStringAttribute(hid_t grp, char* name, const char* str, int length) { * @param name The name of the attribute * @param data The value to write */ -void writeAttribute_d(hid_t grp, char* name, double data) { +void writeAttribute_d(hid_t grp, const char* name, double data) { writeAttribute(grp, name, DOUBLE, &data, 1); } @@ -235,7 +236,7 @@ void writeAttribute_d(hid_t grp, char* name, double data) { * @param name The name of the attribute * @param data The value to write */ -void writeAttribute_f(hid_t grp, char* name, float data) { +void writeAttribute_f(hid_t grp, const char* name, float data) { writeAttribute(grp, name, FLOAT, &data, 1); } @@ -246,7 +247,7 @@ void writeAttribute_f(hid_t grp, char* name, float data) { * @param data The value to write */ -void writeAttribute_i(hid_t grp, char* name, int data) { +void writeAttribute_i(hid_t grp, const char* name, int data) { writeAttribute(grp, name, INT, &data, 1); } @@ -256,7 +257,7 @@ void writeAttribute_i(hid_t grp, char* name, int data) { * @param name The name of the attribute * @param data The value to write */ -void writeAttribute_l(hid_t grp, char* name, long data) { +void writeAttribute_l(hid_t grp, const char* name, long data) { writeAttribute(grp, name, LONG, &data, 1); } @@ -266,7 +267,7 @@ void writeAttribute_l(hid_t grp, char* name, long data) { * @param name The name of the attribute * @param str The string to write */ -void writeAttribute_s(hid_t grp, char* name, const char* str) { +void writeAttribute_s(hid_t grp, const char* name, const char* str) { writeStringAttribute(grp, name, str, strlen(str)); } diff --git a/src/common_io.h b/src/common_io.h index 70ed25993cb110a1faf42a41c08d316c81b54271..ed1c96801c904d9952c7b3ca995b847afdc3fb43 100644 --- a/src/common_io.h +++ b/src/common_io.h @@ -52,10 +52,7 @@ enum DATA_TYPE { *start a run or optional. * */ -enum DATA_IMPORTANCE { - COMPULSORY = 1, - OPTIONAL = 0 -}; +enum DATA_IMPORTANCE { COMPULSORY = 1, OPTIONAL = 0 }; /** * @brief The different particle types present in a GADGET IC file @@ -88,14 +85,14 @@ void duplicate_hydro_gparts(struct part* const parts, void readAttribute(hid_t grp, char* name, enum DATA_TYPE type, void* data); -void writeAttribute(hid_t grp, char* name, enum DATA_TYPE type, void* data, - int num); +void writeAttribute(hid_t grp, const char* name, enum DATA_TYPE type, + void* data, int num); -void writeAttribute_d(hid_t grp, char* name, double data); -void writeAttribute_f(hid_t grp, char* name, float data); -void writeAttribute_i(hid_t grp, char* name, int data); -void writeAttribute_l(hid_t grp, char* name, long data); -void writeAttribute_s(hid_t grp, char* name, const char* str); +void writeAttribute_d(hid_t grp, const char* name, double data); +void writeAttribute_f(hid_t grp, const char* name, float data); +void writeAttribute_i(hid_t grp, const char* name, int data); +void writeAttribute_l(hid_t grp, const char* name, long data); +void writeAttribute_s(hid_t grp, const char* name, const char* str); void createXMFfile(const char* baseName); FILE* prepareXMFfile(const char* baseName); @@ -108,7 +105,6 @@ void writeXMFline(FILE* xmfFile, char* fileName, char* partTypeGroupName, char* name, size_t N, int dim, enum DATA_TYPE type); void writeCodeDescription(hid_t h_file); -void writeSPHflavour(hid_t h_file); void writeUnitSystem(hid_t h_file, struct UnitSystem* us); #endif diff --git a/src/cycle.h b/src/cycle.h index 1278c83e8b43324662bdeb0de75eec08faf4fd82..4925808f5a4c4ea7828bc1a6b7a9490d2d2ca255 100644 --- a/src/cycle.h +++ b/src/cycle.h @@ -334,7 +334,7 @@ typedef unsigned __int64 ticks; extern "C" #endif ticks - __getReg(int whichReg); + __getReg(int whichReg); #pragma intrinsic(__getReg) static __inline ticks getticks(void) { @@ -481,9 +481,9 @@ INLINE_ELAPSED(inline) /* MIPS ZBus */ #if HAVE_MIPS_ZBUS_TIMER #if defined(__mips__) && !defined(HAVE_TICK_COUNTER) +#include <fcntl.h> #include <sys/mman.h> #include <unistd.h> -#include <fcntl.h> typedef uint64_t ticks; diff --git a/src/debug.c b/src/debug.c index 53a03d66aee2c169a555ed00a2efa2d5b984066a..a3647915d96a9456cb6d8177d144dab56fd0b97e 100644 --- a/src/debug.c +++ b/src/debug.c @@ -24,8 +24,8 @@ #include "config.h" #include "const.h" -#include "part.h" #include "debug.h" +#include "part.h" /* Import the right hydro definition */ #if defined(MINIMAL_SPH) @@ -100,8 +100,9 @@ void printgParticle(struct gpart *gparts, long long int id, size_t N) { void printParticle_single(struct part *p, struct xpart *xp) { - printf("## Particle: id=%lld", p->id); + printf("## Particle: id=%lld ", p->id); hydro_debug_particle(p, xp); + printf("\n"); } #ifdef HAVE_METIS diff --git a/src/drift.h b/src/drift.h new file mode 100644 index 0000000000000000000000000000000000000000..05b09bb7910e8cddaf9fb24bb248f120f9db9eea --- /dev/null +++ b/src/drift.h @@ -0,0 +1,101 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_DRIFT_H +#define SWIFT_DRIFT_H + +/* Config parameters. */ +#include "../config.h" + +/* Local headers. */ +#include "const.h" +#include "debug.h" +#include "hydro.h" + +/** + * @brief Perform the 'drift' operation on a #gpart + * + * @param gp The #gpart to drift. + * @param dt The drift time-step + * @param timeBase The minimal allowed time-step size. + * @param ti_old Integer start of time-step + * @param ti_current Integer end of time-step + */ +__attribute__((always_inline)) INLINE static void drift_gpart( + struct gpart* gp, float dt, double timeBase, int ti_old, int ti_current) { + /* Drift... */ + gp->x[0] += gp->v_full[0] * dt; + gp->x[1] += gp->v_full[1] * dt; + gp->x[2] += gp->v_full[2] * dt; + + /* Compute offset since last cell construction */ + gp->x_diff[0] -= gp->v_full[0] * dt; + gp->x_diff[1] -= gp->v_full[1] * dt; + gp->x_diff[2] -= gp->v_full[2] * dt; +} + +/** + * @brief Perform the 'drift' operation on a #part + * + * @param p The #part to drift. + * @param xp The #xpart of the particle. + * @param dt The drift time-step + * @param timeBase The minimal allowed time-step size. + * @param ti_old Integer start of time-step + * @param ti_current Integer end of time-step + */ +__attribute__((always_inline)) INLINE static void drift_part( + struct part* p, struct xpart* xp, float dt, double timeBase, int ti_old, + int ti_current) { + /* Useful quantity */ + const float h_inv = 1.0f / p->h; + + /* Drift... */ + p->x[0] += xp->v_full[0] * dt; + p->x[1] += xp->v_full[1] * dt; + p->x[2] += xp->v_full[2] * dt; + + /* Predict velocities (for hydro terms) */ + p->v[0] += p->a_hydro[0] * dt; + p->v[1] += p->a_hydro[1] * dt; + p->v[2] += p->a_hydro[2] * dt; + + /* Predict smoothing length */ + const float w1 = p->h_dt * h_inv * dt; + if (fabsf(w1) < 0.2f) + p->h *= approx_expf(w1); /* 4th order expansion of exp(w) */ + else + p->h *= expf(w1); + + /* Predict density */ + const float w2 = -3.0f * w1; + if (fabsf(w2) < 0.2f) + p->rho *= approx_expf(w2); /* 4th order expansion of exp(w) */ + else + p->rho *= expf(w2); + + /* Predict the values of the extra fields */ + hydro_predict_extra(p, xp, ti_old, ti_current, timeBase); + + /* Compute offset since last cell construction */ + xp->x_diff[0] -= xp->v_full[0] * dt; + xp->x_diff[1] -= xp->v_full[1] * dt; + xp->x_diff[2] -= xp->v_full[2] * dt; +} + +#endif /* SWIFT_DRIFT_H */ diff --git a/src/engine.c b/src/engine.c index 598f8e8ecb2a0540d5b82c7c3ce2be7a69e78463..59d83757830b62cd5c229b9937f9530462ee7773 100644 --- a/src/engine.c +++ b/src/engine.c @@ -29,11 +29,11 @@ #include <float.h> #include <limits.h> #include <sched.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <stdbool.h> /* MPI headers. */ #ifdef WITH_MPI @@ -56,22 +56,35 @@ #include "error.h" #include "hydro.h" #include "minmax.h" +#include "parallel_io.h" #include "part.h" #include "partition.h" -#include "parallel_io.h" #include "serial_io.h" #include "single_io.h" #include "timers.h" -const char *engine_policy_names[13] = { - "none", "rand", "steal", "keep", - "block", "fix_dt", "cpu_tight", "mpi", - "numa_affinity", "hydro", "self_gravity", "external_gravity", - "cosmology_integration"}; +const char *engine_policy_names[13] = {"none", + "rand", + "steal", + "keep", + "block", + "fix_dt", + "cpu_tight", + "mpi", + "numa_affinity", + "hydro", + "self_gravity", + "external_gravity", + "cosmology_integration"}; /** The rank of the engine as a global variable (for messages). */ int engine_rank; +#ifdef HAVE_SETAFFINITY +/** The initial affinity of the main thread (set by engin_pin()) */ +static cpu_set_t entry_affinity; +#endif + /** * @brief Link a density/force task to a cell. * @@ -112,6 +125,7 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c, const int is_with_external_gravity = (e->policy & engine_policy_external_gravity) == engine_policy_external_gravity; + const int is_fixdt = (e->policy & engine_policy_fixdt) == engine_policy_fixdt; /* Am I the super-cell? */ if (super == NULL && (c->count > 0 || c->gcount > 0)) { @@ -130,9 +144,14 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c, c->drift = scheduler_addtask(s, task_type_drift, task_subtype_none, 0, 0, c, NULL, 0); - /* Add the kick task. */ - c->kick = scheduler_addtask(s, task_type_kick, task_subtype_none, 0, 0, c, - NULL, 0); + /* Add the kick task that matches the policy. */ + if (is_fixdt) { + c->kick = scheduler_addtask(s, task_type_kick_fixdt, task_subtype_none, + 0, 0, c, NULL, 0); + } else { + c->kick = scheduler_addtask(s, task_type_kick, task_subtype_none, 0, 0, + c, NULL, 0); + } if (c->count > 0) { @@ -1799,8 +1818,9 @@ void engine_barrier(struct engine *e, int tid) { /** * @brief Mapping function to collect the data from the kick. + * + * @param c A super-cell. */ - void engine_collect_kick(struct cell *c) { /* Skip super-cells (Their values are already set) */ @@ -1808,15 +1828,13 @@ void engine_collect_kick(struct cell *c) { /* Counters for the different quantities. */ int updated = 0, g_updated = 0; - double e_kin = 0.0, e_int = 0.0, e_pot = 0.0; - float mom[3] = {0.0f, 0.0f, 0.0f}, ang[3] = {0.0f, 0.0f, 0.0f}; - int ti_end_min = max_nr_timesteps, ti_end_max = 0; + int ti_end_min = max_nr_timesteps; /* Only do something is the cell is non-empty */ if (c->count != 0 || c->gcount != 0) { /* If this cell is not split, I'm in trouble. */ - if (!c->split) error("Cell has no super-cell."); + if (!c->split) error("Cell is not split."); /* Collect the values from the progeny. */ for (int k = 0; k < 8; k++) { @@ -1828,36 +1846,197 @@ void engine_collect_kick(struct cell *c) { /* And update */ ti_end_min = min(ti_end_min, cp->ti_end_min); - ti_end_max = max(ti_end_max, cp->ti_end_max); updated += cp->updated; g_updated += cp->g_updated; + } + } + } + + /* Store the collected values in the cell. */ + c->ti_end_min = ti_end_min; + c->updated = updated; + c->g_updated = g_updated; +} + +/** + * @brief Collects the next time-step by making each super-cell recurse + * to collect the minimal of ti_end and the number of updated particles. + * + * @param e The #engine. + */ +void engine_collect_timestep(struct engine *e) { + + int updates = 0, g_updates = 0; + int ti_end_min = max_nr_timesteps; + const struct space *s = e->s; + + /* Collect the cell data. */ + for (int k = 0; k < s->nr_cells; k++) + if (s->cells[k].nodeID == e->nodeID) { + struct cell *c = &s->cells[k]; + + /* Make the top-cells recurse */ + engine_collect_kick(c); + + /* And aggregate */ + ti_end_min = min(ti_end_min, c->ti_end_min); + updates += c->updated; + g_updates += c->g_updated; + } + +/* Aggregate the data from the different nodes. */ +#ifdef WITH_MPI + { + int in_i[1], out_i[1]; + in_i[0] = 0; + out_i[0] = ti_end_min; + if (MPI_Allreduce(out_i, in_i, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD) != + MPI_SUCCESS) + error("Failed to aggregate t_end_min."); + ti_end_min = in_i[0]; + } + { + unsigned long long in_ll[2], out_ll[2]; + out_ll[0] = updates; + out_ll[1] = g_updates; + if (MPI_Allreduce(out_ll, in_ll, 2, MPI_LONG_LONG_INT, MPI_SUM, + MPI_COMM_WORLD) != MPI_SUCCESS) + error("Failed to aggregate energies."); + updates = in_ll[0]; + g_updates = in_ll[1]; + } +#endif + + e->ti_end_min = ti_end_min; + e->updates = updates; + e->g_updates = g_updates; +} + +/** + * @brief Mapping function to collect the data from the drift. + * + * @param c A super-cell. + */ +void engine_collect_drift(struct cell *c) { + + /* Skip super-cells (Their values are already set) */ + if (c->drift != NULL) return; + + /* Counters for the different quantities. */ + double e_kin = 0.0, e_int = 0.0, e_pot = 0.0, mass = 0.0; + double mom[3] = {0.0, 0.0, 0.0}, ang_mom[3] = {0.0, 0.0, 0.0}; + + /* Only do something is the cell is non-empty */ + if (c->count != 0 || c->gcount != 0) { + + /* If this cell is not split, I'm in trouble. */ + if (!c->split) error("Cell has no super-cell."); + + /* Collect the values from the progeny. */ + for (int k = 0; k < 8; k++) { + struct cell *cp = c->progeny[k]; + if (cp != NULL) { + + /* Recurse */ + engine_collect_drift(cp); + + /* And update */ + mass += cp->mass; e_kin += cp->e_kin; e_int += cp->e_int; e_pot += cp->e_pot; mom[0] += cp->mom[0]; mom[1] += cp->mom[1]; mom[2] += cp->mom[2]; - ang[0] += cp->ang[0]; - ang[1] += cp->ang[1]; - ang[2] += cp->ang[2]; + ang_mom[0] += cp->ang_mom[0]; + ang_mom[1] += cp->ang_mom[1]; + ang_mom[2] += cp->ang_mom[2]; } } } /* Store the collected values in the cell. */ - c->ti_end_min = ti_end_min; - c->ti_end_max = ti_end_max; - c->updated = updated; - c->g_updated = g_updated; + c->mass = mass; c->e_kin = e_kin; c->e_int = e_int; c->e_pot = e_pot; c->mom[0] = mom[0]; c->mom[1] = mom[1]; c->mom[2] = mom[2]; - c->ang[0] = ang[0]; - c->ang[1] = ang[1]; - c->ang[2] = ang[2]; + c->ang_mom[0] = ang_mom[0]; + c->ang_mom[1] = ang_mom[1]; + c->ang_mom[2] = ang_mom[2]; +} + +void engine_print_stats(struct engine *e) { + + const struct space *s = e->s; + + double e_kin = 0.0, e_int = 0.0, e_pot = 0.0, mass = 0.0; + double mom[3] = {0.0, 0.0, 0.0}, ang_mom[3] = {0.0, 0.0, 0.0}; + + /* Collect the cell data. */ + for (int k = 0; k < s->nr_cells; k++) + if (s->cells[k].nodeID == e->nodeID) { + struct cell *c = &s->cells[k]; + + /* Make the top-cells recurse */ + engine_collect_drift(c); + + /* And aggregate */ + mass += c->mass; + e_kin += c->e_kin; + e_int += c->e_int; + e_pot += c->e_pot; + mom[0] += c->mom[0]; + mom[1] += c->mom[1]; + mom[2] += c->mom[2]; + ang_mom[0] += c->ang_mom[0]; + ang_mom[1] += c->ang_mom[1]; + ang_mom[2] += c->ang_mom[2]; + } + +/* Aggregate the data from the different nodes. */ +#ifdef WITH_MPI + { + double in[10] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}; + double out[10]; + out[0] = e_kin; + out[1] = e_int; + out[2] = e_pot; + out[3] = mom[0]; + out[4] = mom[1]; + out[5] = mom[2]; + out[6] = ang_mom[0]; + out[7] = ang_mom[1]; + out[8] = ang_mom[2]; + out[9] = mass; + if (MPI_Allreduce(out, in, 10, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD) != + MPI_SUCCESS) + error("Failed to aggregate stats."); + e_kin = out[0]; + e_int = out[1]; + e_pot = out[2]; + mom[0] = out[3]; + mom[1] = out[4]; + mom[2] = out[5]; + ang_mom[0] = out[6]; + ang_mom[1] = out[7]; + ang_mom[2] = out[8]; + mass = out[9]; + } +#endif + + const double e_tot = e_kin + e_int + e_pot; + + /* Print info */ + if (e->nodeID == 0) { + fprintf(e->file_stats, + " %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e\n", + e->time, mass, e_tot, e_kin, e_int, e_pot, mom[0], mom[1], mom[2], + ang_mom[0], ang_mom[1], ang_mom[2]); + fflush(e->file_stats); + } } /** @@ -1868,7 +2047,6 @@ void engine_collect_kick(struct cell *c) { * @param mask The task mask to launch. * @param submask The sub-task mask to launch. */ - void engine_launch(struct engine *e, int nr_runners, unsigned int mask, unsigned int submask) { @@ -1913,18 +2091,18 @@ void engine_init_particles(struct engine *e) { if (e->nodeID == 0) message("Initialising particles"); + engine_prepare(e); + /* Make sure all particles are ready to go */ /* i.e. clean-up any stupid state in the ICs */ if (e->policy & engine_policy_hydro) { - space_map_cells_pre(s, 1, cell_init_parts, NULL); + space_map_cells_pre(s, 0, cell_init_parts, NULL); } if ((e->policy & engine_policy_self_gravity) || (e->policy & engine_policy_external_gravity)) { - space_map_cells_pre(s, 1, cell_init_gparts, NULL); + space_map_cells_pre(s, 0, cell_init_gparts, NULL); } - engine_prepare(e); - engine_marktasks(e); /* Build the masks corresponding to the policy */ @@ -1987,13 +2165,7 @@ void engine_init_particles(struct engine *e) { */ void engine_step(struct engine *e) { - int updates = 0, g_updates = 0; - int ti_end_min = max_nr_timesteps, ti_end_max = 0; - double e_pot = 0.0, e_int = 0.0, e_kin = 0.0; - float mom[3] = {0.0, 0.0, 0.0}; - float ang[3] = {0.0, 0.0, 0.0}; double snapshot_drift_time = 0.; - struct space *s = e->s; TIMER_TIC2; @@ -2002,66 +2174,11 @@ void engine_step(struct engine *e) { e->tic_step = getticks(); - /* Collect the cell data. */ - for (int k = 0; k < s->nr_cells; k++) - if (s->cells[k].nodeID == e->nodeID) { - struct cell *c = &s->cells[k]; - - /* Recurse */ - engine_collect_kick(c); - - /* And aggregate */ - ti_end_min = min(ti_end_min, c->ti_end_min); - ti_end_max = max(ti_end_max, c->ti_end_max); - e_kin += c->e_kin; - e_int += c->e_int; - e_pot += c->e_pot; - updates += c->updated; - g_updates += c->g_updated; - mom[0] += c->mom[0]; - mom[1] += c->mom[1]; - mom[2] += c->mom[2]; - ang[0] += c->ang[0]; - ang[1] += c->ang[1]; - ang[2] += c->ang[2]; - } - -/* Aggregate the data from the different nodes. */ -#ifdef WITH_MPI - { - int in_i[1], out_i[1]; - in_i[0] = 0; - out_i[0] = ti_end_min; - if (MPI_Allreduce(out_i, in_i, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD) != - MPI_SUCCESS) - error("Failed to aggregate t_end_min."); - ti_end_min = in_i[0]; - out_i[0] = ti_end_max; - if (MPI_Allreduce(out_i, in_i, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD) != - MPI_SUCCESS) - error("Failed to aggregate t_end_max."); - ti_end_max = in_i[0]; - } - { - double in_d[5], out_d[5]; - out_d[0] = updates; - out_d[1] = g_updates; - out_d[2] = e_kin; - out_d[3] = e_int; - out_d[4] = e_pot; - if (MPI_Allreduce(out_d, in_d, 5, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD) != - MPI_SUCCESS) - error("Failed to aggregate energies."); - updates = in_d[0]; - g_updates = in_d[1]; - e_kin = in_d[2]; - e_int = in_d[3]; - e_pot = in_d[4]; - } -#endif + /* Recover the (integer) end of the next time-step */ + engine_collect_timestep(e); /* Check for output */ - while (ti_end_min >= e->ti_nextSnapshot && e->ti_nextSnapshot > 0) { + while (e->ti_end_min >= e->ti_nextSnapshot && e->ti_nextSnapshot > 0) { e->ti_old = e->ti_current; e->ti_current = e->ti_nextSnapshot; @@ -2082,7 +2199,7 @@ void engine_step(struct engine *e) { /* Move forward in time */ e->ti_old = e->ti_current; - e->ti_current = ti_end_min; + e->ti_current = e->ti_end_min; e->step += 1; e->time = e->ti_current * e->timeBase + e->timeBegin; e->timeOld = e->ti_old * e->timeBase + e->timeBegin; @@ -2094,15 +2211,15 @@ void engine_step(struct engine *e) { if (e->nodeID == 0) { /* Print some information to the screen */ - printf(" %6d %14e %14e %10d %10d %21.3f\n", e->step, e->time, e->timeStep, - updates, g_updates, e->wallclock_time); + printf(" %6d %14e %14e %10zd %10zd %21.3f\n", e->step, e->time, + e->timeStep, e->updates, e->g_updates, e->wallclock_time); fflush(stdout); + } - /* Write some energy statistics */ - fprintf(e->file_stats, "%d %f %f %f %f %f %f %f %f %f %f %f\n", e->step, - e->time, e_kin, e_int, e_pot, e_kin + e_int + e_pot, mom[0], mom[1], - mom[2], ang[0], ang[1], ang[2]); - fflush(e->file_stats); + /* Save some statistics */ + if (e->time - e->timeLastStatistics >= e->deltaTimeStatistics) { + engine_print_stats(e); + e->timeLastStatistics += e->deltaTimeStatistics; } /* Re-distribute the particles amongst the nodes? */ @@ -2114,11 +2231,17 @@ void engine_step(struct engine *e) { /* Build the masks corresponding to the policy */ unsigned int mask = 0, submask = 0; - /* We always have sort tasks and kick tasks */ + /* We always have sort tasks and init tasks */ mask |= 1 << task_type_sort; - mask |= 1 << task_type_kick; mask |= 1 << task_type_init; + /* Add the correct kick task */ + if (e->policy & engine_policy_fixdt) { + mask |= 1 << task_type_kick_fixdt; + } else { + mask |= 1 << task_type_kick; + } + /* Add the tasks corresponding to hydro operations to the masks */ if (e->policy & engine_policy_hydro) { @@ -2390,23 +2513,58 @@ void engine_dump_snapshot(struct engine *e) { (float)clocks_diff(&time1, &time2), clocks_getunit()); } -#if defined(HAVE_LIBNUMA) && defined(_GNU_SOURCE) -static bool hyperthreads_present(void) { -#ifdef __linux__ - FILE *f = - fopen("/sys/devices/system/cpu/cpu0/topology/thread_siblings_list", "r"); +#ifdef HAVE_SETAFFINITY +/** + * @brief Returns the initial affinity the main thread is using. + */ +static cpu_set_t *engine_entry_affinity() { + + static int use_entry_affinity = 0; + + if (!use_entry_affinity) { + pthread_t engine = pthread_self(); + pthread_getaffinity_np(engine, sizeof(entry_affinity), &entry_affinity); + use_entry_affinity = 1; + } + + return &entry_affinity; +} +#endif + +/** + * @brief Ensure the NUMA node on which we initialise (first touch) everything + * doesn't change before engine_init allocates NUMA-local workers. + */ +void engine_pin() { - int c; - while ((c = fgetc(f)) != EOF && c != ',') +#ifdef HAVE_SETAFFINITY + cpu_set_t *entry_affinity = engine_entry_affinity(); + int pin; + for (pin = 0; pin < CPU_SETSIZE && !CPU_ISSET(pin, entry_affinity); ++pin) ; - fclose(f); - return c == ','; + cpu_set_t affinity; + CPU_ZERO(&affinity); + CPU_SET(pin, &affinity); + if (sched_setaffinity(0, sizeof(affinity), &affinity) != 0) { + error("failed to set engine's affinity"); + } #else - return true; // just guess + error("SWIFT was not compiled with support for pinning."); #endif } + +/** + * @brief Unpins the main thread. + */ +void engine_unpin() { +#ifdef HAVE_SETAFFINITY + pthread_t main_thread = pthread_self(); + pthread_setaffinity_np(main_thread, sizeof(entry_affinity), &entry_affinity); +#else + error("SWIFT was not compiled with support for pinning."); #endif +} /** * @brief init an engine with the given number of threads, queues, and @@ -2418,6 +2576,7 @@ static bool hyperthreads_present(void) { * @param nr_nodes The number of MPI ranks. * @param nodeID The MPI rank of this node. * @param nr_threads The number of threads per MPI rank. + * @param with_aff use processor affinity, if supported. * @param policy The queuing policy to use. * @param verbose Is this #engine talkative ? * @param physical_constants The #phys_const used for this run. @@ -2427,7 +2586,7 @@ static bool hyperthreads_present(void) { void engine_init(struct engine *e, struct space *s, const struct swift_params *params, int nr_nodes, int nodeID, - int nr_threads, int policy, int verbose, + int nr_threads, int with_aff, int policy, int verbose, const struct phys_const *physical_constants, const struct hydro_props *hydro, const struct external_potential *potential) { @@ -2456,6 +2615,7 @@ void engine_init(struct engine *e, struct space *s, e->ti_current = 0; e->timeStep = 0.; e->timeBase = 0.; + e->timeBase_inv = 0.; e->timeFirstSnapshot = parser_get_param_double(params, "Snapshots:time_first"); e->deltaTimeSnapshot = @@ -2467,12 +2627,16 @@ void engine_init(struct engine *e, struct space *s, e->dt_min = parser_get_param_double(params, "TimeIntegration:dt_min"); e->dt_max = parser_get_param_double(params, "TimeIntegration:dt_max"); e->file_stats = NULL; + e->deltaTimeStatistics = + parser_get_param_double(params, "Statistics:delta_time"); + e->timeLastStatistics = e->timeBegin - e->deltaTimeStatistics; e->verbose = verbose; e->count_step = 0; e->wallclock_time = 0.f; e->physical_constants = physical_constants; e->hydro_properties = hydro; e->external_potential = potential; + e->parameter_file = params; engine_rank = nodeID; /* Make the space link back to the engine. */ @@ -2483,74 +2647,117 @@ void engine_init(struct engine *e, struct space *s, if (nr_queues <= 0) nr_queues = e->nr_threads; s->nr_queues = nr_queues; +/* Deal with affinity. For now, just figure out the number of cores. */ #if defined(HAVE_SETAFFINITY) const int nr_cores = sysconf(_SC_NPROCESSORS_ONLN); - int cpuid[nr_cores]; + cpu_set_t *entry_affinity = engine_entry_affinity(); + const int nr_affinity_cores = CPU_COUNT(entry_affinity); + + if (nr_cores > CPU_SETSIZE) /* Unlikely, except on e.g. SGI UV. */ + error("must allocate dynamic cpu_set_t (too many cores per node)"); + + char *buf = malloc((nr_cores + 1) * sizeof(char)); + buf[nr_cores] = '\0'; + for (int j = 0; j < nr_cores; ++j) { + /* Reversed bit order from convention, but same as e.g. Intel MPI's + * I_MPI_PIN_DOMAIN explicit mask: left-to-right, LSB-to-MSB. */ + buf[j] = CPU_ISSET(j, entry_affinity) ? '1' : '0'; + } + + if (verbose && with_aff) message("Affinity at entry: %s", buf); + + int *cpuid = malloc(nr_affinity_cores * sizeof(int)); cpu_set_t cpuset; - if ((policy & engine_policy_cputight) == engine_policy_cputight) { - for (int k = 0; k < nr_cores; k++) cpuid[k] = k; - } else { - /* Get next highest power of 2. */ - int maxint = 1; - while (maxint < nr_cores) maxint *= 2; - cpuid[0] = 0; - int k = 1; - for (int i = 1; i < maxint; i *= 2) - for (int j = maxint / i / 2; j < maxint; j += maxint / i) - if (j < nr_cores && j != 0) cpuid[k++] = j; + int skip = 0; + for (int k = 0; k < nr_affinity_cores; k++) { + int c; + for (c = skip; c < CPU_SETSIZE && !CPU_ISSET(c, entry_affinity); ++c) + ; + cpuid[k] = c; + skip = c + 1; + } + + if (with_aff) { #if defined(HAVE_LIBNUMA) && defined(_GNU_SOURCE) - /* Ascending NUMA distance. Bubblesort(!) for stable equidistant CPUs. */ - if (numa_available() >= 0) { - if (nodeID == 0) message("prefer NUMA-local CPUs"); - - const int home = numa_node_of_cpu(sched_getcpu()); - const int half = nr_cores / 2; - const bool swap_hyperthreads = hyperthreads_present(); - bool done = false; - if (swap_hyperthreads && nodeID == 0) - message("prefer physical cores to hyperthreads"); - - while (!done) { - done = true; - for (int i = 1; i < nr_cores; i++) { - const int node_a = numa_node_of_cpu(cpuid[i - 1]); - const int node_b = numa_node_of_cpu(cpuid[i]); - - /* Avoid using local hyperthreads over unused remote physical cores. - * Assume two hyperthreads, and that cpuid >= half partitions them. - */ - const int thread_a = swap_hyperthreads && cpuid[i - 1] >= half; - const int thread_b = swap_hyperthreads && cpuid[i] >= half; - - bool swap = thread_a > thread_b; - if (thread_a == thread_b) - swap = numa_distance(home, node_a) > numa_distance(home, node_b); - - if (swap) { - const int t = cpuid[i - 1]; - cpuid[i - 1] = cpuid[i]; - cpuid[i] = t; - done = false; + if ((policy & engine_policy_cputight) != engine_policy_cputight) { + + if (numa_available() >= 0) { + if (nodeID == 0) message("prefer NUMA-distant CPUs"); + + /* Get list of numa nodes of all available cores. */ + int *nodes = malloc(nr_affinity_cores * sizeof(int)); + int nnodes = 0; + for (int i = 0; i < nr_affinity_cores; i++) { + nodes[i] = numa_node_of_cpu(cpuid[i]); + if (nodes[i] > nnodes) nnodes = nodes[i]; + } + nnodes += 1; + + /* Count cores per node. */ + int *core_counts = malloc(nnodes * sizeof(int)); + for (int i = 0; i < nr_affinity_cores; i++) { + core_counts[nodes[i]] = 0; + } + for (int i = 0; i < nr_affinity_cores; i++) { + core_counts[nodes[i]] += 1; + } + + /* Index cores within each node. */ + int *core_indices = malloc(nr_affinity_cores * sizeof(int)); + for (int i = nr_affinity_cores - 1; i >= 0; i--) { + core_indices[i] = core_counts[nodes[i]]; + core_counts[nodes[i]] -= 1; + } + + /* Now sort so that we pick adjacent cpuids from different nodes + * by sorting internal node core indices. */ + int done = 0; + while (!done) { + done = 1; + for (int i = 1; i < nr_affinity_cores; i++) { + if (core_indices[i] < core_indices[i - 1]) { + int t = cpuid[i - 1]; + cpuid[i - 1] = cpuid[i]; + cpuid[i] = t; + + t = core_indices[i - 1]; + core_indices[i - 1] = core_indices[i]; + core_indices[i] = t; + done = 0; + } } } + + free(nodes); + free(core_counts); + free(core_indices); } } #endif + } else { + if (nodeID == 0) message("no processor affinity used"); + + } /* with_aff */ - if (nodeID == 0) { + /* Avoid (unexpected) interference between engine and runner threads. We can + * do this once we've made at least one call to engine_entry_affinity and + * maybe numa_node_of_cpu(sched_getcpu()), even if the engine isn't already + * pinned. Also unpin this when asked to not pin at all (!with_aff). */ + engine_unpin(); +#endif + + if (with_aff) { #ifdef WITH_MPI - printf("[%04i] %s engine_init: cpu map is [ ", nodeID, - clocks_get_timesincestart()); + printf("[%04i] %s engine_init: cpu map is [ ", nodeID, + clocks_get_timesincestart()); #else - printf("%s engine_init: cpu map is [ ", clocks_get_timesincestart()); + printf("%s engine_init: cpu map is [ ", clocks_get_timesincestart()); #endif - for (int i = 0; i < nr_cores; i++) printf("%i ", cpuid[i]); - printf("].\n"); - } + for (int i = 0; i < nr_affinity_cores; i++) printf("%i ", cpuid[i]); + printf("].\n"); } -#endif /* Are we doing stuff in parallel? */ if (nr_nodes > 1) { @@ -2570,8 +2777,10 @@ void engine_init(struct engine *e, struct space *s, if (e->nodeID == 0) { e->file_stats = fopen("energy.txt", "w"); fprintf(e->file_stats, - "# Step Time E_kin E_int E_pot E_tot " - "p_x p_y p_z ang_x ang_y ang_z\n"); + "# %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s\n", + "Time", "Mass", "E_tot", "E_kin", "E_int", "E_pot", "p_x", "p_y", + "p_z", "ang_x", "ang_y", "ang_z"); + fflush(e->file_stats); } /* Print policy */ @@ -2597,6 +2806,7 @@ void engine_init(struct engine *e, struct space *s, /* Deal with timestep */ e->timeBase = (e->timeEnd - e->timeBegin) / max_nr_timesteps; + e->timeBase_inv = 1.0 / e->timeBase; e->ti_current = 0; /* Fixed time-step case */ @@ -2687,19 +2897,24 @@ void engine_init(struct engine *e, struct space *s, if (pthread_create(&e->runners[k].thread, NULL, &runner_main, &e->runners[k]) != 0) error("Failed to create runner thread."); - if (e->policy & engine_policy_setaffinity) { + + /* Try to pin the runner to a given core */ + if (with_aff && + (e->policy & engine_policy_setaffinity) == engine_policy_setaffinity) { #if defined(HAVE_SETAFFINITY) /* Set a reasonable queue ID. */ - e->runners[k].cpuid = cpuid[k % nr_cores]; + int coreid = k % nr_affinity_cores; + e->runners[k].cpuid = cpuid[coreid]; + if (nr_queues < e->nr_threads) - e->runners[k].qid = cpuid[k % nr_cores] * nr_queues / nr_cores; + e->runners[k].qid = cpuid[coreid] * nr_queues / nr_affinity_cores; else e->runners[k].qid = k; /* Set the cpu mask to zero | e->id. */ CPU_ZERO(&cpuset); - CPU_SET(cpuid[k % nr_cores], &cpuset); + CPU_SET(cpuid[coreid], &cpuset); /* Apply this mask to the runner's pthread. */ if (pthread_setaffinity_np(e->runners[k].thread, sizeof(cpu_set_t), @@ -2713,9 +2928,23 @@ void engine_init(struct engine *e, struct space *s, e->runners[k].cpuid = k; e->runners[k].qid = k * nr_queues / e->nr_threads; } - /* message( "runner %i on cpuid=%i with qid=%i." , e->runners[k].id , */ - /* e->runners[k].cpuid , e->runners[k].qid ); */ + if (verbose) { + if (with_aff) + message("runner %i on cpuid=%i with qid=%i.", e->runners[k].id, + e->runners[k].cpuid, e->runners[k].qid); + else + message("runner %i using qid=%i no cpuid.", e->runners[k].id, + e->runners[k].qid); + } + } + +/* Free the affinity stuff */ +#if defined(HAVE_SETAFFINITY) + if (with_aff) { + free(cpuid); + free(buf); } +#endif /* Wait for the runner threads to be in place. */ while (e->barrier_running || e->barrier_launch) diff --git a/src/engine.h b/src/engine.h index a830a37538d7356d0d5de7c67778e8ef7fcc1ed0..392cd9f25c975213340497cacc13451a4b5618b9 100644 --- a/src/engine.h +++ b/src/engine.h @@ -39,16 +39,15 @@ /* Includes. */ #include "hydro_properties.h" #include "lock.h" +#include "parser.h" +#include "partition.h" +#include "physical_constants.h" +#include "potentials.h" #include "proxy.h" #include "runner.h" #include "scheduler.h" #include "space.h" #include "task.h" -#include "parser.h" -#include "partition.h" -#include "physical_constants.h" -#include "potentials.h" -#include "threadpool.h" #include "units.h" /* Some constants. */ @@ -111,6 +110,9 @@ struct engine { /* The task scheduler. */ struct scheduler sched; + /* Common threadpool for all the engine's tasks. */ + struct threadpool threadpool; + /* The minimum and maximum allowed dt */ double dt_min, dt_max; @@ -133,6 +135,13 @@ struct engine { /* Time base */ double timeBase; + double timeBase_inv; + + /* Minimal ti_end for the next time-step */ + int ti_end_min; + + /* Number of particles updated */ + size_t updates, g_updates; /* Snapshot information */ double timeFirstSnapshot; @@ -141,8 +150,10 @@ struct engine { char snapshotBaseName[200]; struct UnitSystem *snapshotUnits; - /* File for statistics */ + /* Statistics information */ FILE *file_stats; + double timeLastStatistics; + double deltaTimeStatistics; /* The current step number. */ int step; @@ -194,8 +205,8 @@ struct engine { /* Properties of external gravitational potential */ const struct external_potential *external_potential; - /* Common threadpool for all the engine's tasks. */ - struct threadpool threadpool; + /* The (parsed) parameter file */ + const struct swift_params *parameter_file; }; /* Function prototypes. */ @@ -204,7 +215,7 @@ void engine_compute_next_snapshot_time(struct engine *e); void engine_dump_snapshot(struct engine *e); void engine_init(struct engine *e, struct space *s, const struct swift_params *params, int nr_nodes, int nodeID, - int nr_threads, int policy, int verbose, + int nr_threads, int with_aff, int policy, int verbose, const struct phys_const *physical_constants, const struct hydro_props *hydro, const struct external_potential *potential); @@ -226,5 +237,7 @@ void engine_redistribute(struct engine *e); struct link *engine_addlink(struct engine *e, struct link *l, struct task *t); void engine_print_policy(struct engine *e); int engine_is_done(struct engine *e); +void engine_pin(); +void engine_unpin(); #endif /* SWIFT_ENGINE_H */ diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index 4dd8d5b7c7194ae072f90e7703907500c208b9b9..0f62511eced181fbf3b5b781a50314dd08f7c0ef 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -31,11 +31,10 @@ * @param phys_const The physical constants in internal units. * @param gp Pointer to the g-particle data. */ -__attribute__((always_inline)) - INLINE static float gravity_compute_timestep_external( - const struct external_potential* potential, - const struct phys_const* const phys_const, - const struct gpart* const gp) { +__attribute__((always_inline)) INLINE static float +gravity_compute_timestep_external(const struct external_potential* potential, + const struct phys_const* const phys_const, + const struct gpart* const gp) { float dt = FLT_MAX; @@ -55,10 +54,9 @@ __attribute__((always_inline)) * @param phys_const The physical constants in internal units. * @param gp Pointer to the g-particle data. */ -__attribute__((always_inline)) - INLINE static float gravity_compute_timestep_self( - const struct phys_const* const phys_const, - const struct gpart* const gp) { +__attribute__((always_inline)) INLINE static float +gravity_compute_timestep_self(const struct phys_const* const phys_const, + const struct gpart* const gp) { float dt = FLT_MAX; @@ -73,8 +71,8 @@ __attribute__((always_inline)) * * @param gp The particle to act upon */ -__attribute__((always_inline)) - INLINE static void gravity_first_init_gpart(struct gpart* gp) {} +__attribute__((always_inline)) INLINE static void gravity_first_init_gpart( + struct gpart* gp) {} /** * @brief Prepares a g-particle for the gravity calculation @@ -84,8 +82,8 @@ __attribute__((always_inline)) * * @param gp The particle to act upon */ -__attribute__((always_inline)) - INLINE static void gravity_init_part(struct gpart* gp) { +__attribute__((always_inline)) INLINE static void gravity_init_part( + struct gpart* gp) { /* Zero the acceleration */ gp->a_grav[0] = 0.f; @@ -100,8 +98,8 @@ __attribute__((always_inline)) * * @param gp The particle to act upon */ -__attribute__((always_inline)) - INLINE static void gravity_end_force(struct gpart* gp) {} +__attribute__((always_inline)) INLINE static void gravity_end_force( + struct gpart* gp) {} /** * @brief Computes the gravitational acceleration induced by external potentials diff --git a/src/gravity/Default/gravity_debug.h b/src/gravity/Default/gravity_debug.h index 72ae5fd55f399448d78c6f2d1533c7f007f16dd1..21d775d703c8bd7000ad03386fe818124642a8f1 100644 --- a/src/gravity/Default/gravity_debug.h +++ b/src/gravity/Default/gravity_debug.h @@ -17,8 +17,8 @@ * ******************************************************************************/ -__attribute__((always_inline)) - INLINE static void gravity_debug_particle(struct gpart* p) { +__attribute__((always_inline)) INLINE static void gravity_debug_particle( + struct gpart* p) { printf( "x=[%.3e,%.3e,%.3e], " "v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e],\n " diff --git a/src/hydro.h b/src/hydro.h index aacbb6ac1d16b38133ee573ee2b7ad95918fc9e5..b2ae9d57c399ecea818e9f3dc7db238e01487a9a 100644 --- a/src/hydro.h +++ b/src/hydro.h @@ -19,20 +19,24 @@ #ifndef SWIFT_HYDRO_H #define SWIFT_HYDRO_H -#include "./const.h" +/* Includes. */ +#include "const.h" +#include "hydro_properties.h" +#include "kernel_hydro.h" +#include "part.h" /* Import the right functions */ #if defined(MINIMAL_SPH) -#include "./hydro/Minimal/hydro_iact.h" #include "./hydro/Minimal/hydro.h" +#include "./hydro/Minimal/hydro_iact.h" #define SPH_IMPLEMENTATION "Minimal version of SPH (e.g. Price 2010)" #elif defined(GADGET2_SPH) -#include "./hydro/Gadget2/hydro_iact.h" #include "./hydro/Gadget2/hydro.h" +#include "./hydro/Gadget2/hydro_iact.h" #define SPH_IMPLEMENTATION "Gadget-2 version of SPH (Springel 2005)" #elif defined(DEFAULT_SPH) -#include "./hydro/Default/hydro_iact.h" #include "./hydro/Default/hydro.h" +#include "./hydro/Default/hydro_iact.h" #define SPH_IMPLEMENTATION "Default version of SPH" #else #error "Invalid choice of SPH variant" diff --git a/src/hydro/Default/hydro.h b/src/hydro/Default/hydro.h index b4ed2daf385691958d5849b0ac2d651ac6f98d34..4a6b1900374eb6b422e6fa7422901293b36fd5eb 100644 --- a/src/hydro/Default/hydro.h +++ b/src/hydro/Default/hydro.h @@ -27,7 +27,7 @@ * */ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( - struct part* p, struct xpart* xp, + const struct part* p, const struct xpart* xp, const struct hydro_props* hydro_properties) { const float CFL_condition = hydro_properties->CFL_condition; @@ -53,9 +53,8 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( * @param p The particle to act upon * @param xp The extended particle data to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_first_init_part(struct part* p, struct xpart* xp) { -} +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part* p, struct xpart* xp) {} /** * @brief Prepares a particle for the density calculation. @@ -65,8 +64,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_init_part(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_init_part( + struct part* p) { p->density.wcount = 0.f; p->density.wcount_dh = 0.f; p->rho = 0.f; @@ -86,8 +85,8 @@ __attribute__((always_inline)) * @param p The particle to act upon * @param time The current time */ -__attribute__((always_inline)) - INLINE static void hydro_end_density(struct part* p, float time) { +__attribute__((always_inline)) INLINE static void hydro_end_density( + struct part* p, float time) { /* Some smoothing length multiples. */ const float h = p->h; @@ -171,8 +170,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_reset_acceleration(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_reset_acceleration( + struct part* p) { /* Reset the acceleration. */ p->a_hydro[0] = 0.0f; @@ -218,8 +217,8 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_force(struct part* p) {} +__attribute__((always_inline)) INLINE static void hydro_end_force( + struct part* p) {} /** * @brief Kick the additional variables @@ -239,16 +238,17 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_convert_quantities(struct part* p) {} +__attribute__((always_inline)) INLINE static void hydro_convert_quantities( + struct part* p) {} /** * @brief Returns the internal energy of a particle * * @param p The particle of interest + * @param dt Time since the last kick */ -__attribute__((always_inline)) - INLINE static float hydro_get_internal_energy(struct part* p) { +__attribute__((always_inline)) INLINE static float hydro_get_internal_energy( + const struct part* p, float dt) { return p->u; } diff --git a/src/hydro/Default/hydro_debug.h b/src/hydro/Default/hydro_debug.h index 2e7c3d683aa18eee7a550ac89517e3bd01e42107..79ee392d46ca75a2c097bf045b2d82c9f3dc96c0 100644 --- a/src/hydro/Default/hydro_debug.h +++ b/src/hydro/Default/hydro_debug.h @@ -17,8 +17,8 @@ * ******************************************************************************/ -__attribute__((always_inline)) - INLINE static void hydro_debug_particle(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_debug_particle( + struct part* p, struct xpart* xp) { printf( "x=[%.3e,%.3e,%.3e], " "v=[%.3e,%.3e,%.3e],v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e],\n " diff --git a/src/hydro/Default/hydro_iact.h b/src/hydro/Default/hydro_iact.h index 4f85299b9d61b3a66389bac3527a63068ab96db9..4d651b61bd934388414d54fa813820111d26e682 100644 --- a/src/hydro/Default/hydro_iact.h +++ b/src/hydro/Default/hydro_iact.h @@ -268,11 +268,9 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_density( * @brief Density loop (non-symmetric vectorized version) */ -__attribute__((always_inline)) - INLINE static void runner_iact_nonsym_vec_density(float *R2, float *Dx, - float *Hi, float *Hj, - struct part **pi, - struct part **pj) { +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_vec_density(float *R2, float *Dx, float *Hi, float *Hj, + struct part **pi, struct part **pj) { #ifdef VECTORIZE diff --git a/src/hydro/Default/hydro_io.h b/src/hydro/Default/hydro_io.h index 09a7f4c7caa6a2a9fcf77c8d83b0ffcab2ef8b54..de71963b05149fa0b2df6222424478a6ad9b1f44 100644 --- a/src/hydro/Default/hydro_io.h +++ b/src/hydro/Default/hydro_io.h @@ -104,10 +104,6 @@ void writeSPHflavour(hid_t h_grpsph) { /* Kernel function description */ writeAttribute_s(h_grpsph, "Kernel", kernel_name); - // writeAttribute_f(h_grpsph, "Kernel eta", const_eta_kernel); - // writeAttribute_f(h_grpsph, "Weighted N_ngb", kernel_nwneigh); - // writeAttribute_f(h_grpsph, "Delta N_ngb", const_delta_nwneigh); - // writeAttribute_f(h_grpsph, "Hydro gamma", const_hydro_gamma); /* Viscosity and thermal conduction */ writeAttribute_s(h_grpsph, "Thermal Conductivity Model", @@ -123,11 +119,6 @@ void writeSPHflavour(hid_t h_grpsph) { writeAttribute_f(h_grpsph, "Viscosity decay length", const_viscosity_length); /* Time integration properties */ - // writeAttribute_f(h_grpsph, "CFL parameter", const_cfl); - // writeAttribute_f(h_grpsph, "Maximal ln(Delta h) change over dt", - // const_ln_max_h_change); - // writeAttribute_f(h_grpsph, "Maximal Delta h change over dt", - // exp(const_ln_max_h_change)); writeAttribute_f(h_grpsph, "Maximal Delta u change over dt", const_max_u_change); } diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 9fa1aae9dbb13ac3aa7e2271f30ef57e91ae85ae..0973acb0fb46411c778f2551fbe91621825f0278 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -25,7 +25,7 @@ * */ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( - struct part* p, struct xpart* xp, + const struct part* p, const struct xpart* xp, const struct hydro_props* hydro_properties) { const float CFL_condition = hydro_properties->CFL_condition; @@ -46,9 +46,8 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( * @param p The particle to act upon * @param xp The extended particle data to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_first_init_part(struct part* p, struct xpart* xp) { -} +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part* p, struct xpart* xp) {} /** * @brief Prepares a particle for the density calculation. @@ -58,8 +57,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_init_part(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_init_part( + struct part* p) { p->density.wcount = 0.f; p->density.wcount_dh = 0.f; p->rho = 0.f; @@ -79,8 +78,8 @@ __attribute__((always_inline)) * @param p The particle to act upon * @param ti_current The current time (on the integer timeline) */ -__attribute__((always_inline)) - INLINE static void hydro_end_density(struct part* p, int ti_current) { +__attribute__((always_inline)) INLINE static void hydro_end_density( + struct part* p, int ti_current) { /* Some smoothing length multiples. */ const float h = p->h; @@ -148,8 +147,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_reset_acceleration(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_reset_acceleration( + struct part* p) { /* Reset the acceleration. */ p->a_hydro[0] = 0.0f; @@ -193,8 +192,8 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_force(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_end_force( + struct part* p) { p->entropy_dt *= (const_hydro_gamma - 1.f) * powf(p->rho, -(const_hydro_gamma - 1.f)); @@ -230,8 +229,8 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_convert_quantities(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_convert_quantities( + struct part* p) { p->entropy = (const_hydro_gamma - 1.f) * p->entropy * powf(p->rho, -(const_hydro_gamma - 1.f)); @@ -241,10 +240,13 @@ __attribute__((always_inline)) * @brief Returns the internal energy of a particle * * @param p The particle of interest + * @param dt Time since the last kick */ -__attribute__((always_inline)) - INLINE static float hydro_get_internal_energy(struct part* p) { +__attribute__((always_inline)) INLINE static float hydro_get_internal_energy( + const struct part* p, float dt) { + + const float entropy = p->entropy + p->entropy_dt * dt; - return p->entropy * powf(p->rho, const_hydro_gamma - 1.f) * + return entropy * powf(p->rho, const_hydro_gamma - 1.f) * (1.f / (const_hydro_gamma - 1.f)); } diff --git a/src/hydro/Gadget2/hydro_debug.h b/src/hydro/Gadget2/hydro_debug.h index 4f00d8e020f9eaac30fe7f272ca1248d7e4eec58..31e89d438bc96c0f0f2ba56249664d28036cb607 100644 --- a/src/hydro/Gadget2/hydro_debug.h +++ b/src/hydro/Gadget2/hydro_debug.h @@ -17,8 +17,8 @@ * ******************************************************************************/ -__attribute__((always_inline)) - INLINE static void hydro_debug_particle(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_debug_particle( + struct part* p, struct xpart* xp) { printf( "x=[%.3e,%.3e,%.3e], " "v=[%.3e,%.3e,%.3e],v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e],\n " diff --git a/src/hydro/Gadget2/hydro_io.h b/src/hydro/Gadget2/hydro_io.h index 41f3348db10172c1d0d5813debb50365252a413b..b977f25386fab0787c925635297a48fa85a8df24 100644 --- a/src/hydro/Gadget2/hydro_io.h +++ b/src/hydro/Gadget2/hydro_io.h @@ -83,8 +83,8 @@ __attribute__((always_inline)) INLINE static void hydro_write_particles( writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "SmoothingLength", FLOAT, N, 1, parts, N_total, mpi_rank, offset, h, us, UNIT_CONV_LENGTH); - writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Entropy", - FLOAT, N, 1, parts, N_total, mpi_rank, offset, entropy, us, + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Entropy", FLOAT, N, + 1, parts, N_total, mpi_rank, offset, entropy, us, UNIT_CONV_ENTROPY_PER_UNIT_MASS); writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "ParticleIDs", ULONGLONG, N, 1, parts, N_total, mpi_rank, offset, id, us, @@ -104,10 +104,6 @@ void writeSPHflavour(hid_t h_grpsph) { /* Kernel function description */ writeAttribute_s(h_grpsph, "Kernel", kernel_name); - // writeAttribute_f(h_grpsph, "Kernel eta", const_eta_kernel); - // writeAttribute_f(h_grpsph, "Weighted N_ngb", kernel_nwneigh); - // writeAttribute_f(h_grpsph, "Delta N_ngb", const_delta_nwneigh); - // writeAttribute_f(h_grpsph, "Hydro gamma", const_hydro_gamma); /* Viscosity and thermal conduction */ writeAttribute_s(h_grpsph, "Thermal Conductivity Model", @@ -116,11 +112,4 @@ void writeSPHflavour(hid_t h_grpsph) { "Legacy Gadget-2 as in Springel (2005)"); writeAttribute_f(h_grpsph, "Viscosity alpha", const_viscosity_alpha); writeAttribute_f(h_grpsph, "Viscosity beta", 3.f); - - /* Time integration properties */ - // writeAttribute_f(h_grpsph, "CFL parameter", const_cfl); - // writeAttribute_f(h_grpsph, "Maximal ln(Delta h) change over dt", - // const_ln_max_h_change); - // writeAttribute_f(h_grpsph, "Maximal Delta h change over dt", - // exp(const_ln_max_h_change)); } diff --git a/src/hydro/Gizmo/hydro.h b/src/hydro/Gizmo/hydro.h index f3553a009c22a2f6353796e8a278f0db7d66d294..f69dc3f1798f014e895c4a63760805b1739cec94 100644 --- a/src/hydro/Gizmo/hydro.h +++ b/src/hydro/Gizmo/hydro.h @@ -39,17 +39,16 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( * @param p The particle to act upon * @param xp The extended particle data to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_first_init_part(struct part* p, struct xpart* xp) { -} +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part* p, struct xpart* xp) {} /** * @brief Prepares a particle for the volume calculation. * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_init_part(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_init_part( + struct part* p) { #ifdef SPH_GRADIENTS /* use the old volumes to estimate new primitive variables to be used for the @@ -127,8 +126,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_volume(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_end_volume( + struct part* p) { /* Some smoothing length multiples. */ const float h = p->h; @@ -387,8 +386,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_gradient( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_gradient(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_end_gradient( + struct part* p) { #ifndef SPH_GRADIENTS float h, ih, ih2, ih3; @@ -531,8 +530,8 @@ __attribute__((always_inline)) * @param p The particle to act upon * @param xp The extended particle data to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_prepare_fluxes(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_prepare_fluxes( + struct part* p, struct xpart* xp) { /* initialize variables used for timestep calculation */ p->timestepvars.vmax = 0.0f; @@ -546,8 +545,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_reset_acceleration(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_reset_acceleration( + struct part* p) { /* figure out what to put here */ } @@ -559,8 +558,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_fluxes(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_end_fluxes( + struct part* p) { /* do nothing */ } @@ -572,8 +571,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_convert_quantities(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_convert_quantities( + struct part* p) { float volume; GFLOAT m; @@ -605,17 +604,17 @@ __attribute__((always_inline)) } // MATTHIEU -__attribute__((always_inline)) - INLINE static void hydro_end_density(struct part* p, float time) {} +__attribute__((always_inline)) INLINE static void hydro_end_density( + struct part* p, float time) {} __attribute__((always_inline)) INLINE static void hydro_prepare_force( struct part* p, struct xpart* xp, int ti_current, double timeBase) {} __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part* p, struct xpart* xp, int t0, int t1, double timeBase) {} -__attribute__((always_inline)) - INLINE static void hydro_end_force(struct part* p) {} +__attribute__((always_inline)) INLINE static void hydro_end_force( + struct part* p) {} __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part* p, struct xpart* xp, float dt, float half_dt) {} -__attribute__((always_inline)) - INLINE static float hydro_get_internal_energy(struct part* p) { +__attribute__((always_inline)) INLINE static float hydro_get_internal_energy( + struct part* p) { return 0.f; } diff --git a/src/hydro/Gizmo/hydro_debug.h b/src/hydro/Gizmo/hydro_debug.h index 2cc957ed883436ce57e9d53d00a073693c9495df..365d85a2f651cf98b0713e8d82f11ae70fa9beaa 100644 --- a/src/hydro/Gizmo/hydro_debug.h +++ b/src/hydro/Gizmo/hydro_debug.h @@ -17,8 +17,8 @@ * ******************************************************************************/ -__attribute__((always_inline)) - INLINE static void hydro_debug_particle(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_debug_particle( + struct part* p, struct xpart* xp) { printf( "x=[%.16e,%.16e,%.16e], " "v=[%.3e,%.3e,%.3e], a=[%.3e,%.3e,%.3e], volume=%.3e\n", diff --git a/src/hydro/Gizmo/hydro_iact.h b/src/hydro/Gizmo/hydro_iact.h index 4fe875d3d07315051ef8b3051665a9ea0ef261b8..30a8d6cbebc851b44a5ee2339950aec9e15057c0 100644 --- a/src/hydro/Gizmo/hydro_iact.h +++ b/src/hydro/Gizmo/hydro_iact.h @@ -194,11 +194,9 @@ __attribute__((always_inline)) INLINE static void runner_iact_hydro_loop1( } /* this corresponds to task_subtype_hydro_loop1 */ -__attribute__((always_inline)) - INLINE static void runner_iact_nonsym_hydro_loop1(float r2, float *dx, - float hi, float hj, - struct part *pi, - struct part *pj) { +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_hydro_loop1(float r2, float *dx, float hi, float hj, + struct part *pi, struct part *pj) { float r; float xi; @@ -487,11 +485,9 @@ __attribute__((always_inline)) INLINE static void runner_iact_hydro_loop2( #endif } -__attribute__((always_inline)) - INLINE static void runner_iact_nonsym_hydro_loop2(float r2, float *dx, - float hi, float hj, - struct part *pi, - struct part *pj) { +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_hydro_loop2(float r2, float *dx, float hi, float hj, + struct part *pi, struct part *pj) { #ifndef SPH_GRADIENTS @@ -1025,11 +1021,9 @@ __attribute__((always_inline)) INLINE static void runner_iact_hydro_loop3( } /* this corresponds to task_subtype_fluxes */ -__attribute__((always_inline)) - INLINE static void runner_iact_nonsym_hydro_loop3(float r2, float *dx, - float hi, float hj, - struct part *pi, - struct part *pj) { +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_hydro_loop3(float r2, float *dx, float hi, float hj, + struct part *pi, struct part *pj) { runner_iact_fluxes_common(r2, dx, hi, hj, pi, pj, 0); } diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index 01957065cf5b1d89bb839449ac60b9ec965c2c47..4222daafe82e7dc977cd87f57a5b9a235d505f00 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -31,7 +31,7 @@ * */ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( - struct part* p, struct xpart* xp, + const struct part* p, const struct xpart* xp, const struct hydro_props* hydro_properties) { const float CFL_condition = hydro_properties->CFL_condition; @@ -53,8 +53,8 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( * @param p The particle to act upon * @param xp The extended particle data to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_first_init_part(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part* p, struct xpart* xp) { xp->u_full = p->u; } @@ -68,8 +68,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_init_part(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_init_part( + struct part* p) { p->density.wcount = 0.f; p->density.wcount_dh = 0.f; p->rho = 0.f; @@ -88,8 +88,8 @@ __attribute__((always_inline)) * @param p The particle to act upon * @param time The current time */ -__attribute__((always_inline)) - INLINE static void hydro_end_density(struct part* p, float time) { +__attribute__((always_inline)) INLINE static void hydro_end_density( + struct part* p, float time) { /* Some smoothing length multiples. */ const float h = p->h; @@ -143,8 +143,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_reset_acceleration(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_reset_acceleration( + struct part* p) { /* Reset the acceleration. */ p->a_hydro[0] = 0.0f; @@ -172,14 +172,7 @@ __attribute__((always_inline)) __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part* p, struct xpart* xp, int t0, int t1, double timeBase) { - const float dt = t1 - t0; - - /* Predict internal energy */ - const float w = p->u_dt / p->u * dt; - if (fabsf(w) < 0.2f) - p->u *= approx_expf(w); /* 4th order expansion of exp(w) */ - else - p->u *= expf(w); + p->u = xp->u_full; /* Need to recompute the pressure as well */ p->force.pressure = p->rho * p->u * (const_hydro_gamma - 1.f); @@ -194,8 +187,8 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_force(struct part* p) {} +__attribute__((always_inline)) INLINE static void hydro_end_force( + struct part* p) {} /** * @brief Kick the additional variables @@ -228,8 +221,8 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_convert_quantities(struct part* p) {} +__attribute__((always_inline)) INLINE static void hydro_convert_quantities( + struct part* p) {} /** * @brief Returns the internal energy of a particle @@ -239,9 +232,10 @@ __attribute__((always_inline)) * energy from the thermodynamic variable. * * @param p The particle of interest + * @param dt Time since the last kick */ -__attribute__((always_inline)) - INLINE static float hydro_get_internal_energy(struct part* p) { +__attribute__((always_inline)) INLINE static float hydro_get_internal_energy( + const struct part* p, float dt) { return p->u; } diff --git a/src/hydro/Minimal/hydro_debug.h b/src/hydro/Minimal/hydro_debug.h index 85fdbac0a7893d575e52629600a5407c1bf77fcc..127ba75e99418b6a5dc197a44ccdc77de3cdef15 100644 --- a/src/hydro/Minimal/hydro_debug.h +++ b/src/hydro/Minimal/hydro_debug.h @@ -17,8 +17,8 @@ * ******************************************************************************/ -__attribute__((always_inline)) - INLINE static void hydro_debug_particle(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_debug_particle( + struct part* p, struct xpart* xp) { printf( "x=[%.3e,%.3e,%.3e], " "v=[%.3e,%.3e,%.3e],v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e], " diff --git a/src/hydro/Minimal/hydro_iact.h b/src/hydro/Minimal/hydro_iact.h index 3427ec538613842f8fbcf0d8ba5f9ba5a0b8d540..f453d8fa1c495472af27ccf98356a3dab0894e98 100644 --- a/src/hydro/Minimal/hydro_iact.h +++ b/src/hydro/Minimal/hydro_iact.h @@ -131,18 +131,14 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( const float P_over_rho_j = pressurej / (rhoj * rhoj) * pj->rho_dh; /* Compute dv dot r. */ - 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]; - dvdr *= r_inv; - - /* Compute the relative velocity. (This is 0 if the particles move away from - * each other and negative otherwise) */ - const float omega_ij = fminf(dvdr, 0.f); + 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]; /* Compute sound speeds */ const float ci = sqrtf(const_hydro_gamma * pressurei / rhoi); const float cj = sqrtf(const_hydro_gamma * pressurej / rhoj); - const float v_sig = ci + cj + 3.f * omega_ij; + const float v_sig = ci + cj; /* SPH acceleration term */ const float sph_term = (P_over_rho_i * wi_dr + P_over_rho_j * wj_dr) * r_inv; @@ -157,8 +153,8 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( pj->a_hydro[2] += mi * sph_term * dx[2]; /* Get the time derivative for u. */ - pi->u_dt += P_over_rho_i * mj * dvdr * wi_dr; - pj->u_dt += P_over_rho_j * mi * dvdr * wj_dr; + pi->u_dt += P_over_rho_i * mj * dvdr * r_inv * wi_dr; + pj->u_dt += P_over_rho_j * mi * dvdr * r_inv * wj_dr; /* Get the time derivative for h. */ pi->h_dt -= mj * dvdr * r_inv / rhoj * wi_dr; @@ -208,18 +204,14 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( const float P_over_rho_j = pressurej / (rhoj * rhoj) * pj->rho_dh; /* Compute dv dot r. */ - 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]; - dvdr *= r_inv; - - /* Compute the relative velocity. (This is 0 if the particles move away from - * each other and negative otherwise) */ - const float omega_ij = fminf(dvdr, 0.f); + 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]; /* Compute sound speeds */ const float ci = sqrtf(const_hydro_gamma * pressurei / rhoi); const float cj = sqrtf(const_hydro_gamma * pressurej / rhoj); - const float v_sig = ci + cj + 3.f * omega_ij; + const float v_sig = ci + cj; /* SPH acceleration term */ const float sph_term = (P_over_rho_i * wi_dr + P_over_rho_j * wj_dr) * r_inv; @@ -230,7 +222,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( pi->a_hydro[2] -= mj * sph_term * dx[2]; /* Get the time derivative for u. */ - pi->u_dt += P_over_rho_i * mj * dvdr * wi_dr; + pi->u_dt += P_over_rho_i * mj * dvdr * r_inv * wi_dr; /* Get the time derivative for h. */ pi->h_dt -= mj * dvdr * r_inv / rhoj * wi_dr; diff --git a/src/hydro/Minimal/hydro_io.h b/src/hydro/Minimal/hydro_io.h index 43926d526b47fa8f1b92bb862edabefb7417de3c..1bbfe1065358017e0b27e2131ff717848221fe9c 100644 --- a/src/hydro/Minimal/hydro_io.h +++ b/src/hydro/Minimal/hydro_io.h @@ -104,9 +104,6 @@ void writeSPHflavour(hid_t h_grpsph) { /* Kernel function description */ writeAttribute_s(h_grpsph, "Kernel", kernel_name); - // writeAttribute_f(h_grpsph, "Kernel eta", const_eta_kernel); - // writeAttribute_f(h_grpsph, "Weighted N_ngb", kernel_nwneigh); - // writeAttribute_f(h_grpsph, "Delta N_ngb", const_delta_nwneigh); writeAttribute_f(h_grpsph, "Hydro gamma", const_hydro_gamma); /* Viscosity and thermal conduction */ @@ -115,11 +112,6 @@ void writeSPHflavour(hid_t h_grpsph) { writeAttribute_s(h_grpsph, "Viscosity Model", "No model"); /* Time integration properties */ - // writeAttribute_f(h_grpsph, "CFL parameter", const_cfl); - // writeAttribute_f(h_grpsph, "Maximal ln(Delta h) change over dt", - // const_ln_max_h_change); - // writeAttribute_f(h_grpsph, "Maximal Delta h change over dt", - // exp(const_ln_max_h_change)); writeAttribute_f(h_grpsph, "Maximal Delta u change over dt", const_max_u_change); } diff --git a/src/hydro_properties.c b/src/hydro_properties.c index 4bedad7e0ccbca7656694c070c6140d1163db9cc..b4e37d672408ad3c0adf1f37fcd4fcbd50095d92 100644 --- a/src/hydro_properties.c +++ b/src/hydro_properties.c @@ -26,8 +26,8 @@ /* Local headers. */ #include "error.h" -#include "kernel_hydro.h" #include "hydro.h" +#include "kernel_hydro.h" void hydro_props_init(struct hydro_props *p, const struct swift_params *params) { @@ -55,7 +55,7 @@ void hydro_props_print(const struct hydro_props *p) { message("Hydrodynamic kernel: %s with %.2f +/- %.2f neighbours (eta=%f).", kernel_name, p->target_neighbours, p->delta_neighbours, p->eta_neighbours); - message("Hydrodynamic integration: CFL parmeter: %.4f.", p->CFL_condition); + message("Hydrodynamic integration: CFL parameter: %.4f.", p->CFL_condition); message( "Hydrodynamic integration: Max change of volume: %.2f " "(max|dlog(h)/dt|=%f).", diff --git a/src/intrinsics.h b/src/intrinsics.h index 21b8c8e68bc45d8799db496ff30ac0cfb289acea..27e0bcc729b58493aed8c7eae7dfcdfc8f0855aa 100644 --- a/src/intrinsics.h +++ b/src/intrinsics.h @@ -26,8 +26,8 @@ * This is a wrapper for the GCC intrinsics with an implementation (from * Hacker's Delight) if the compiler intrinsics are not available. */ -__attribute__((always_inline)) - INLINE static int intrinsics_clz(unsigned int x) { +__attribute__((always_inline)) INLINE static int intrinsics_clz( + unsigned int x) { #ifdef __GNUC__ /* Use GCC intrinsics if possible */ @@ -66,8 +66,8 @@ __attribute__((always_inline)) * This is a wrapper for the GCC intrinsics with an implementation (from * Hacker's Delight) if the compiler intrinsics are not available. */ -__attribute__((always_inline)) - INLINE static int intrinsics_popcount(unsigned int x) { +__attribute__((always_inline)) INLINE static int intrinsics_popcount( + unsigned int x) { #ifdef __GNUC__ /* Use GCC intrinsics if possible */ diff --git a/src/kernel_gravity.h b/src/kernel_gravity.h index cca449efa6dde73eac428d1e20fa5c28156360fa..fedc046eed3bc64ed09120537cf6863179b171a6 100644 --- a/src/kernel_gravity.h +++ b/src/kernel_gravity.h @@ -26,11 +26,11 @@ #include "vector.h" #define const_iepsilon (1. / const_epsilon) -#define const_iepsilon2 (const_iepsilon *const_iepsilon) -#define const_iepsilon3 (const_iepsilon2 *const_iepsilon) -#define const_iepsilon4 (const_iepsilon2 *const_iepsilon2) -#define const_iepsilon5 (const_iepsilon3 *const_iepsilon2) -#define const_iepsilon6 (const_iepsilon3 *const_iepsilon3) +#define const_iepsilon2 (const_iepsilon * const_iepsilon) +#define const_iepsilon3 (const_iepsilon2 * const_iepsilon) +#define const_iepsilon4 (const_iepsilon2 * const_iepsilon2) +#define const_iepsilon5 (const_iepsilon3 * const_iepsilon2) +#define const_iepsilon6 (const_iepsilon3 * const_iepsilon3) /* The gravity kernel is defined as a degree 6 polynomial in the distance r. The resulting value should be post-multiplied with r^-3, resulting @@ -42,18 +42,28 @@ #define kernel_grav_degree 6 #define kernel_grav_ivals 2 #define kernel_grav_scale (2 * const_iepsilon) -static float kernel_grav_coeffs - [(kernel_grav_degree + 1) * (kernel_grav_ivals + 1)] = { - 32.0f * const_iepsilon6, -192.0f / 5.0f * const_iepsilon5, - 0.0f, 32.0f / 3.0f * const_iepsilon3, - 0.0f, 0.0f, - 0.0f, -32.0f / 3.0f * const_iepsilon6, - 192.0f / 5.0f * const_iepsilon5, -48.0f * const_iepsilon4, - 64.0f / 3.0f * const_iepsilon3, 0.0f, - 0.0f, -1.0f / 15.0f, - 0.0f, 0.0f, - 0.0f, 0.0f, - 0.0f, 0.0f, +static float + kernel_grav_coeffs[(kernel_grav_degree + 1) * (kernel_grav_ivals + 1)] = { + 32.0f * const_iepsilon6, + -192.0f / 5.0f * const_iepsilon5, + 0.0f, + 32.0f / 3.0f * const_iepsilon3, + 0.0f, + 0.0f, + 0.0f, + -32.0f / 3.0f * const_iepsilon6, + 192.0f / 5.0f * const_iepsilon5, + -48.0f * const_iepsilon4, + 64.0f / 3.0f * const_iepsilon3, + 0.0f, + 0.0f, + -1.0f / 15.0f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, 1.0f}; /** @@ -76,8 +86,8 @@ __attribute__((always_inline)) INLINE static void kernel_grav_eval(float x, * version). */ -__attribute__((always_inline)) - INLINE static void kernel_grav_eval_vec(vector *x, vector *w) { +__attribute__((always_inline)) INLINE static void kernel_grav_eval_vec( + vector *x, vector *w) { vector ind, c[kernel_grav_degree + 1]; int j, k; @@ -179,8 +189,8 @@ __attribute__((always_inline)) INLINE static void blender_eval_vec(vector *x, * distance x (Vectorized version). Gives a sensible answer only if x<2. */ -__attribute__((always_inline)) - INLINE static void blender_deval_vec(vector *x, vector *w, vector *dw_dx) { +__attribute__((always_inline)) INLINE static void blender_deval_vec( + vector *x, vector *w, vector *dw_dx) { vector ind, c[blender_degree + 1]; int j, k; diff --git a/src/kernel_hydro.h b/src/kernel_hydro.h index 06f950b0e2f3aec68055ba7976b32dc00980589e..b1774d8f35b7eddb6c2fdb0c341fa6299de74582 100644 --- a/src/kernel_hydro.h +++ b/src/kernel_hydro.h @@ -137,22 +137,22 @@ static const float kernel_coeffs[(kernel_degree + 1) * (kernel_ivals + 1)] /* Ok, now comes the real deal. */ /* First some powers of gamma = H/h */ -#define kernel_gamma2 ((float)(kernel_gamma *kernel_gamma)) -#define kernel_gamma3 ((float)(kernel_gamma *kernel_gamma *kernel_gamma)) +#define kernel_gamma2 ((float)(kernel_gamma * kernel_gamma)) +#define kernel_gamma3 ((float)(kernel_gamma * kernel_gamma * kernel_gamma)) #define kernel_gamma4 \ - ((float)(kernel_gamma *kernel_gamma *kernel_gamma *kernel_gamma)) + ((float)(kernel_gamma * kernel_gamma * kernel_gamma * kernel_gamma)) #define kernel_igamma ((float)(1. / kernel_gamma)) -#define kernel_igamma2 ((float)(kernel_igamma *kernel_igamma)) -#define kernel_igamma3 ((float)(kernel_igamma *kernel_igamma *kernel_igamma)) +#define kernel_igamma2 ((float)(kernel_igamma * kernel_igamma)) +#define kernel_igamma3 ((float)(kernel_igamma * kernel_igamma * kernel_igamma)) #define kernel_igamma4 \ - ((float)(kernel_igamma *kernel_igamma *kernel_igamma *kernel_igamma)) + ((float)(kernel_igamma * kernel_igamma * kernel_igamma * kernel_igamma)) /* The number of branches */ #define kernel_ivals_f ((float)(kernel_ivals)) /* Kernel self contribution (i.e. W(0,h)) */ #define kernel_root \ - ((float)(kernel_coeffs[kernel_degree]) * kernel_constant *kernel_igamma3) + ((float)(kernel_coeffs[kernel_degree]) * kernel_constant * kernel_igamma3) /** * @brief Computes the kernel function and its derivative. @@ -200,8 +200,8 @@ __attribute__((always_inline)) INLINE static void kernel_deval( * @param u The ratio of the distance to the smoothing length $u = x/h$. * @param W (return) The value of the kernel function $W(x,h)$. */ -__attribute__((always_inline)) - INLINE static void kernel_eval(float u, float *restrict W) { +__attribute__((always_inline)) INLINE static void kernel_eval( + float u, float *restrict W) { /* Go to the range [0,1[ from [0,H[ */ const float x = u * kernel_igamma; @@ -246,8 +246,8 @@ static const vector kernel_igamma4_vec = FILL_VEC((float)kernel_igamma4); * @param w (return) The value of the kernel function $W(x,h)$. * @param dw_dx (return) The norm of the gradient of $|\\nabla W(x,h)|$. */ -__attribute__((always_inline)) - INLINE static void kernel_deval_vec(vector *u, vector *w, vector *dw_dx) { +__attribute__((always_inline)) INLINE static void kernel_deval_vec( + vector *u, vector *w, vector *dw_dx) { /* Go to the range [0,1[ from [0,H[ */ vector x; diff --git a/src/kick.h b/src/kick.h new file mode 100644 index 0000000000000000000000000000000000000000..df3bd4cc6ce9819d0b65640db51d2ed20a7d59fe --- /dev/null +++ b/src/kick.h @@ -0,0 +1,114 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_KICK_H +#define SWIFT_KICK_H + +/* Config parameters. */ +#include "../config.h" + +/* Local headers. */ +#include "const.h" +#include "debug.h" + +/** + * @brief Perform the 'kick' operation on a #gpart + * + * @param gp The #gpart to kick. + * @param new_dti The (integer) time-step for this kick. + * @param timeBase The minimal allowed time-step size. + */ +__attribute__((always_inline)) INLINE static void kick_gpart(struct gpart* gp, + int new_dti, + double timeBase) { + + /* Compute the time step for this kick */ + const int ti_start = (gp->ti_begin + gp->ti_end) / 2; + const int ti_end = gp->ti_end + new_dti / 2; + const double dt = (ti_end - ti_start) * timeBase; + const double half_dt = (ti_end - gp->ti_end) * timeBase; + + /* Move particle forward in time */ + gp->ti_begin = gp->ti_end; + gp->ti_end = gp->ti_begin + new_dti; + + /* Kick particles in momentum space */ + gp->v_full[0] += gp->a_grav[0] * dt; + gp->v_full[1] += gp->a_grav[1] * dt; + gp->v_full[2] += gp->a_grav[2] * dt; + + /* Extra kick work */ + gravity_kick_extra(gp, dt, half_dt); +} + +/** + * @brief Perform the 'kick' operation on a #part + * + * @param p The #part to kick. + * @param xp The #xpart of the particle. + * @param new_dti The (integer) time-step for this kick. + * @param timeBase The minimal allowed time-step size. + */ +__attribute__((always_inline)) INLINE static void kick_part(struct part* p, + struct xpart* xp, + int new_dti, + double timeBase) { + + /* Compute the time step for this kick */ + const int ti_start = (p->ti_begin + p->ti_end) / 2; + const int ti_end = p->ti_end + new_dti / 2; + const double dt = (ti_end - ti_start) * timeBase; + const double half_dt = (ti_end - p->ti_end) * timeBase; + + /* Move particle forward in time */ + p->ti_begin = p->ti_end; + p->ti_end = p->ti_begin + new_dti; + if (p->gpart != NULL) { + p->gpart->ti_begin = p->ti_begin; + p->gpart->ti_end = p->ti_end; + } + + /* Get the acceleration */ + float a_tot[3] = {p->a_hydro[0], p->a_hydro[1], p->a_hydro[2]}; + if (p->gpart != NULL) { + a_tot[0] += p->gpart->a_grav[0]; + a_tot[1] += p->gpart->a_grav[1]; + a_tot[1] += p->gpart->a_grav[2]; + } + + /* Kick particles in momentum space */ + xp->v_full[0] += a_tot[0] * dt; + xp->v_full[1] += a_tot[1] * dt; + xp->v_full[2] += a_tot[2] * dt; + if (p->gpart != NULL) { + p->gpart->v_full[0] = xp->v_full[0]; + p->gpart->v_full[1] = xp->v_full[1]; + p->gpart->v_full[2] = xp->v_full[2]; + } + + /* Go back by half-step for the hydro velocity */ + p->v[0] = xp->v_full[0] - half_dt * a_tot[0]; + p->v[1] = xp->v_full[1] - half_dt * a_tot[1]; + p->v[2] = xp->v_full[2] - half_dt * a_tot[2]; + + /* Extra kick work */ + hydro_kick_extra(p, xp, dt, half_dt); + if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt, half_dt); +} + +#endif /* SWIFT_KICK_H */ diff --git a/src/lock.h b/src/lock.h index 84bfa7bec77a5f23a69a7288c460a94a6857e20a..31f80605efb29bfaaadc65e25ba4f31679f8fbe8 100644 --- a/src/lock.h +++ b/src/lock.h @@ -27,7 +27,7 @@ #ifdef PTHREAD_SPINLOCK #include <pthread.h> -#define lock_type pthread_spinlock_t +#define swift_lock_type pthread_spinlock_t #define lock_init(l) (pthread_spin_init(l, PTHREAD_PROCESS_PRIVATE) != 0) #define lock_destroy(l) (pthread_spin_destroy(l) != 0) #define lock_lock(l) (pthread_spin_lock(l) != 0) @@ -37,7 +37,7 @@ #elif defined(PTHREAD_LOCK) #include <pthread.h> -#define lock_type pthread_mutex_t +#define swift_lock_type pthread_mutex_t #define lock_init(l) (pthread_mutex_init(l, NULL) != 0) #define lock_destroy(l) (pthread_mutex_destroy(l) != 0) #define lock_lock(l) (pthread_mutex_lock(l) != 0) @@ -46,7 +46,7 @@ #define lock_unlock_blind(l) pthread_mutex_unlock(l) #else -#define lock_type volatile int +#define swift_lock_type volatile int #define lock_init(l) (*(l) = 0) #define lock_destroy(l) 0 INLINE static int lock_lock(volatile int *l) { diff --git a/src/map.c b/src/map.c index da13fbfb4ac00ed58184f7fe818826c82265a1de..fbe57fde7b1e29c49b0f27d86d177245dd9a27e2 100644 --- a/src/map.c +++ b/src/map.c @@ -18,10 +18,10 @@ * ******************************************************************************/ +#include "map.h" #include <stdio.h> #include <stdlib.h> #include "error.h" -#include "map.h" /** * @brief Mapping function to draw a specific cell (gnuplot). diff --git a/src/map.h b/src/map.h index 0753c2641af6deb050c1dcef6bcd3ae4621ae6aa..950a5fd96ebdc7177b41912b1565163f33de8701 100644 --- a/src/map.h +++ b/src/map.h @@ -22,8 +22,8 @@ #ifndef SWIFT_MAP_H #define SWIFT_MAP_H -#include "part.h" #include "cell.h" +#include "part.h" void map_cells_plot(struct cell *c, void *data); void map_check(struct part *p, struct cell *c, void *data); diff --git a/src/parallel_io.c b/src/parallel_io.c index 4579be8f04ae687140413383e061988c9783b570..e779b56a85da3db72ea860fb336fa42037fbcd0e 100644 --- a/src/parallel_io.c +++ b/src/parallel_io.c @@ -529,7 +529,7 @@ void read_ic_parallel(char* fileName, double dim[3], struct part** parts, void write_output_parallel(struct engine* e, const char* baseName, struct UnitSystem* us, int mpi_rank, int mpi_size, MPI_Comm comm, MPI_Info info) { - hid_t h_file = 0, h_grp = 0, h_grpsph = 0; + hid_t h_file = 0, h_grp = 0; const size_t Ngas = e->s->nr_parts; const size_t Ntot = e->s->nr_gparts; int periodic = e->s->periodic; @@ -633,10 +633,17 @@ void write_output_parallel(struct engine* e, const char* baseName, writeCodeDescription(h_file); /* Print the SPH parameters */ - h_grpsph = H5Gcreate(h_file, "/SPH", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - if (h_grpsph < 0) error("Error while creating SPH group"); - writeSPHflavour(h_grpsph); - H5Gclose(h_grpsph); + h_grp = H5Gcreate(h_file, "/SPH", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (h_grp < 0) error("Error while creating SPH group"); + writeSPHflavour(h_grp); + H5Gclose(h_grp); + + /* Print the runtime parameters */ + h_grp = + H5Gcreate(h_file, "/Parameters", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (h_grp < 0) error("Error while creating parameters group"); + parser_write_params_to_hdf5(e->parameter_file, h_grp); + H5Gclose(h_grp); /* Print the system of Units */ writeUnitSystem(h_file, us); diff --git a/src/parser.c b/src/parser.c index 49b035db05722d13d1ce48129b8fae8bfc1ad86b..74c277f036c733b5b1fbff4f2cb477b52169e2c6 100644 --- a/src/parser.c +++ b/src/parser.c @@ -22,14 +22,15 @@ /* Some standard headers. */ /* Needs to be included so that strtok returns char * instead of a int *. */ -#include <string.h> -#include <stdlib.h> #include <ctype.h> +#include <stdlib.h> +#include <string.h> /* This object's header. */ #include "parser.h" /* Local headers. */ +#include "common_io.h" #include "error.h" #define PARSER_COMMENT_STRING "#" @@ -255,7 +256,7 @@ static void parse_value(char *line, struct swift_params *params) { /* Check that it is a parameter inside a section.*/ if (*line == ' ' || *line == '\t') { parse_section_param(line, &isFirstParam, section, params); - } else {/*Else it is the start of a new section or standalone parameter. */ + } else { /*Else it is the start of a new section or standalone parameter. */ /* Take first token as the parameter name. */ token = strtok(line, " :\t"); strcpy(tmpStr, token); @@ -276,7 +277,13 @@ static void parse_value(char *line, struct swift_params *params) { find_duplicate_params(params, tmpStr); strcpy(section, tmpSectionName); - strcpy(params->section[params->sectionCount++].name, tmpSectionName); + strcpy(params->section[params->sectionCount].name, tmpSectionName); + if (params->sectionCount == PARSER_MAX_NO_OF_SECTIONS - 1) { + error( + "Maximal number of sections in parameter file reached. Aborting !"); + } else { + params->sectionCount++; + } inSection = 1; isFirstParam = 1; } else { @@ -294,7 +301,14 @@ static void parse_value(char *line, struct swift_params *params) { /* Must be a standalone parameter so no need to prefix name with a * section. */ strcpy(params->data[params->paramCount].name, tmpStr); - strcpy(params->data[params->paramCount++].value, token); + strcpy(params->data[params->paramCount].value, token); + if (params->paramCount == PARSER_MAX_NO_OF_PARAMS - 1) { + error( + "Maximal number of parameters in parameter file reached. Aborting " + "!"); + } else { + params->paramCount++; + } inSection = 0; isFirstParam = 1; } @@ -346,7 +360,12 @@ static void parse_section_param(char *line, int *isFirstParam, find_duplicate_params(params, paramName); strcpy(params->data[params->paramCount].name, paramName); - strcpy(params->data[params->paramCount++].value, token); + strcpy(params->data[params->paramCount].value, token); + if (params->paramCount == PARSER_MAX_NO_OF_PARAMS - 1) { + error("Maximal number of parameters in parameter file reached. Aborting !"); + } else { + params->paramCount++; + } } /** @@ -376,7 +395,8 @@ int parser_get_param_int(const struct swift_params *params, const char *name) { } } - error("Cannot find '%s' in the structure, in file '%s'.", name,params->fileName); + error("Cannot find '%s' in the structure, in file '%s'.", name, + params->fileName); return 0; } @@ -408,7 +428,8 @@ char parser_get_param_char(const struct swift_params *params, } } - error("Cannot find '%s' in the structure, in file '%s'.", name,params->fileName); + error("Cannot find '%s' in the structure, in file '%s'.", name, + params->fileName); return 0; } @@ -440,7 +461,8 @@ float parser_get_param_float(const struct swift_params *params, } } - error("Cannot find '%s' in the structure, in file '%s'.", name,params->fileName); + error("Cannot find '%s' in the structure, in file '%s'.", name, + params->fileName); return 0.f; } @@ -471,7 +493,8 @@ double parser_get_param_double(const struct swift_params *params, } } - error("Cannot find '%s' in the structure, in file '%s'.", name,params->fileName); + error("Cannot find '%s' in the structure, in file '%s'.", name, + params->fileName); return 0.; } @@ -558,3 +581,11 @@ void parser_write_params_to_file(const struct swift_params *params, fclose(file); } + +#if defined(HAVE_HDF5) +void parser_write_params_to_hdf5(const struct swift_params *params, hid_t grp) { + + for (int i = 0; i < params->paramCount; i++) + writeAttribute_s(grp, params->data[i].name, params->data[i].value); +} +#endif diff --git a/src/parser.h b/src/parser.h index 2d50ddc49bf2231235bbb73040b067f77462d33e..21156a37b3bc76d8c3ba01385cb991b2fe213a85 100644 --- a/src/parser.h +++ b/src/parser.h @@ -22,9 +22,14 @@ /* Config parameters. */ #include "../config.h" +#if defined(HAVE_HDF5) +#include <hdf5.h> +#endif + /* Some constants. */ #define PARSER_MAX_LINE_SIZE 256 -#define PARSER_MAX_NO_OF_PARAMS 512 +#define PARSER_MAX_NO_OF_PARAMS 256 +#define PARSER_MAX_NO_OF_SECTIONS 64 /* A parameter in the input file */ struct parameter { @@ -38,7 +43,7 @@ struct section { /* The array of parameters read from a file */ struct swift_params { - struct section section[PARSER_MAX_NO_OF_PARAMS]; + struct section section[PARSER_MAX_NO_OF_SECTIONS]; struct parameter data[PARSER_MAX_NO_OF_PARAMS]; int sectionCount; int paramCount; @@ -59,4 +64,8 @@ double parser_get_param_double(const struct swift_params *params, void parser_get_param_string(const struct swift_params *params, const char *name, char *retParam); +#if defined(HAVE_HDF5) +void parser_write_params_to_hdf5(const struct swift_params *params, hid_t grp); +#endif + #endif /* SWIFT_PARSER_H */ diff --git a/src/partition.c b/src/partition.c index 70249a679edfe72bda97eddfc918a8526659d995..432943f05f78b41086c7d0d9cc29b1456f094d54 100644 --- a/src/partition.c +++ b/src/partition.c @@ -31,11 +31,11 @@ #include "../config.h" /* Standard headers. */ +#include <float.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> -#include <float.h> /* MPI headers. */ #ifdef WITH_MPI @@ -59,13 +59,12 @@ /* Simple descriptions of initial partition types for reports. */ const char *initial_partition_name[] = { - "gridded cells", "vectorized point associated cells", + "gridded cells", "vectorized point associated cells", "METIS particle weighted cells", "METIS unweighted cells"}; /* Simple descriptions of repartition types for reports. */ const char *repartition_name[] = { - "no", - "METIS edge and vertex time weighted cells", + "no", "METIS edge and vertex time weighted cells", "METIS particle count vertex weighted cells", "METIS time edge weighted cells", "METIS particle count vertex and time edge cells"}; @@ -782,8 +781,9 @@ void partition_initial_partition(struct partition *initial_partition, struct cell *c; /* If we've got the wrong number of nodes, fail. */ - if (nr_nodes != initial_partition->grid[0] * initial_partition->grid[1] * - initial_partition->grid[2]) + if (nr_nodes != + initial_partition->grid[0] * initial_partition->grid[1] * + initial_partition->grid[2]) error("Grid size does not match number of nodes."); /* Run through the cells and set their nodeID. */ @@ -792,8 +792,9 @@ void partition_initial_partition(struct partition *initial_partition, c = &s->cells[k]; for (j = 0; j < 3; j++) ind[j] = c->loc[j] / s->dim[j] * initial_partition->grid[j]; - c->nodeID = ind[0] + initial_partition->grid[0] * - (ind[1] + initial_partition->grid[1] * ind[2]); + c->nodeID = ind[0] + + initial_partition->grid[0] * + (ind[1] + initial_partition->grid[1] * ind[2]); // message("cell at [%e,%e,%e]: ind = [%i,%i,%i], nodeID = %i", c->loc[0], // c->loc[1], c->loc[2], ind[0], ind[1], ind[2], c->nodeID); } diff --git a/src/potentials.h b/src/potentials.h index 50a8903095a8a8218e8d02e3f42af07e40be5b43..c3db5a3d2231c93b1d83aa94bca83f7f7d7106bc 100644 --- a/src/potentials.h +++ b/src/potentials.h @@ -30,8 +30,8 @@ /* Local includes. */ #include "const.h" #include "error.h" -#include "part.h" #include "parser.h" +#include "part.h" #include "physical_constants.h" #include "units.h" @@ -58,11 +58,10 @@ struct external_potential { * @param phys_const The physical constants in internal units. * @param g Pointer to the g-particle data. */ -__attribute__((always_inline)) - INLINE static float external_gravity_pointmass_timestep( - const struct external_potential* potential, - const struct phys_const* const phys_const, - const struct gpart* const g) { +__attribute__((always_inline)) INLINE static float +external_gravity_pointmass_timestep(const struct external_potential* potential, + const struct phys_const* const phys_const, + const struct gpart* const g) { const float G_newton = phys_const->const_newton_G; const float dx = g->x[0] - potential->point_mass.x; diff --git a/src/proxy.c b/src/proxy.c index 02263a5653bdcdd2d1bf0a86523ed1a599d4bf21..efe3a3eec108d44d5b9bf8b4718dc025464f8762 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -249,8 +249,8 @@ void proxy_parts_exch2(struct proxy *p) { } while (p->nr_parts_in > p->size_parts_in); free(p->parts_in); free(p->xparts_in); - if ((p->parts_in = (struct part *)malloc( - sizeof(struct part) *p->size_parts_in)) == NULL || + if ((p->parts_in = (struct part *)malloc(sizeof(struct part) * + p->size_parts_in)) == NULL || (p->xparts_in = (struct xpart *)malloc(sizeof(struct xpart) * p->size_parts_in)) == NULL) error("Failed to re-allocate parts_in buffers."); @@ -310,7 +310,7 @@ void proxy_parts_load(struct proxy *p, const struct part *parts, } while (p->nr_parts_out + N > p->size_parts_out); struct part *tp; struct xpart *txp; - if ((tp = (struct part *)malloc(sizeof(struct part) *p->size_parts_out)) == + if ((tp = (struct part *)malloc(sizeof(struct part) * p->size_parts_out)) == NULL || (txp = (struct xpart *)malloc(sizeof(struct xpart) * p->size_parts_out)) == NULL) @@ -395,8 +395,8 @@ void proxy_init(struct proxy *p, int mynodeID, int nodeID) { /* Allocate the part send and receive buffers, if needed. */ if (p->parts_in == NULL) { p->size_parts_in = proxy_buffinit; - if ((p->parts_in = (struct part *)malloc( - sizeof(struct part) *p->size_parts_in)) == NULL || + if ((p->parts_in = (struct part *)malloc(sizeof(struct part) * + p->size_parts_in)) == NULL || (p->xparts_in = (struct xpart *)malloc(sizeof(struct xpart) * p->size_parts_in)) == NULL) error("Failed to allocate parts_in buffers."); @@ -404,8 +404,8 @@ void proxy_init(struct proxy *p, int mynodeID, int nodeID) { p->nr_parts_in = 0; if (p->parts_out == NULL) { p->size_parts_out = proxy_buffinit; - if ((p->parts_out = (struct part *)malloc( - sizeof(struct part) *p->size_parts_out)) == NULL || + if ((p->parts_out = (struct part *)malloc(sizeof(struct part) * + p->size_parts_out)) == NULL || (p->xparts_out = (struct xpart *)malloc(sizeof(struct xpart) * p->size_parts_out)) == NULL) error("Failed to allocate parts_out buffers."); diff --git a/src/queue.c b/src/queue.c index 6b788d7376ba4bdc95f1b1d918ab52a9514e7b4a..dfdac883f9713eb57bb2dc45eb97774983e3a9b2 100644 --- a/src/queue.c +++ b/src/queue.c @@ -133,7 +133,7 @@ void queue_init(struct queue *q, struct task *tasks) { struct task *queue_gettask(struct queue *q, const struct task *prev, int blocking) { - lock_type *qlock = &q->lock; + swift_lock_type *qlock = &q->lock; struct task *res = NULL; /* Grab the task lock. */ diff --git a/src/queue.h b/src/queue.h index 9ce52ea5404db727f29d0f1cf898f5f5a4f6d935..b28039a30724fa0c086f9111470af2566933e3ac 100644 --- a/src/queue.h +++ b/src/queue.h @@ -41,7 +41,7 @@ extern int queue_counter[queue_counter_count]; struct queue { /* The lock to access this queue. */ - lock_type lock; + swift_lock_type lock; /* Size, count and next element. */ int size, count; diff --git a/src/riemann.h b/src/riemann.h index ad37490d7249bafe776b58a609064cbd0bc23abe..d647b021167317d14f4cd7316d09c247794f3d23 100644 --- a/src/riemann.h +++ b/src/riemann.h @@ -21,11 +21,11 @@ /* gives us const_hydro_gamma and tells us which floating point type to use */ #include "const.h" +#include "error.h" +#include "float.h" #include "math.h" #include "stdio.h" -#include "float.h" #include "stdlib.h" -#include "error.h" #define HLLC_SOLVER diff --git a/src/riemann/riemann_exact.h b/src/riemann/riemann_exact.h index b768cde5f4f5dfd0463cc8a582a1af0a17607bbe..a2f3c30fb1daf5d53bf35abe4ca7e73eafba6018 100644 --- a/src/riemann/riemann_exact.h +++ b/src/riemann/riemann_exact.h @@ -78,9 +78,9 @@ __attribute__((always_inline)) INLINE static GFLOAT riemann_fb(GFLOAT p, * @param aL The left sound speed * @param aR The right sound speed */ -__attribute__((always_inline)) - INLINE static GFLOAT riemann_f(GFLOAT p, GFLOAT* WL, GFLOAT* WR, GFLOAT vL, - GFLOAT vR, GFLOAT aL, GFLOAT aR) { +__attribute__((always_inline)) INLINE static GFLOAT riemann_f( + GFLOAT p, GFLOAT* WL, GFLOAT* WR, GFLOAT vL, GFLOAT vR, GFLOAT aL, + GFLOAT aR) { return riemann_fb(p, WL, aL) + riemann_fb(p, WR, aR) + (vR - vL); } diff --git a/src/riemann/riemann_hllc.h b/src/riemann/riemann_hllc.h index 3fcc8b534ce65d4d364c400dc43e1992f39264b9..6c583f6410f53ed64d630082926d816129768fab 100644 --- a/src/riemann/riemann_hllc.h +++ b/src/riemann/riemann_hllc.h @@ -63,13 +63,15 @@ __attribute__((always_inline)) INLINE static void riemann_solve_for_flux( all these speeds are along the interface normal, since uL and uR are */ qL = 1.; if (pstar > WL[4]) { - qL = sqrtf(1. + 0.5 * (const_hydro_gamma + 1.) / const_hydro_gamma * - (pstar / WL[4] - 1.)); + qL = sqrtf(1. + + 0.5 * (const_hydro_gamma + 1.) / const_hydro_gamma * + (pstar / WL[4] - 1.)); } qR = 1.; if (pstar > WR[4]) { - qR = sqrtf(1. + 0.5 * (const_hydro_gamma + 1.) / const_hydro_gamma * - (pstar / WR[4] - 1.)); + qR = sqrtf(1. + + 0.5 * (const_hydro_gamma + 1.) / const_hydro_gamma * + (pstar / WR[4] - 1.)); } SL = uL - aL * qL; SR = uR + aR * qR; diff --git a/src/runner.c b/src/runner.c index 7a2bcd8563c62250f44183aef3f4b1457623633e..25bd27f109b09f93fafe78fe32350a2dceea0187 100644 --- a/src/runner.c +++ b/src/runner.c @@ -42,52 +42,67 @@ #include "atomic.h" #include "const.h" #include "debug.h" +#include "drift.h" #include "engine.h" #include "error.h" #include "gravity.h" -#include "hydro_properties.h" #include "hydro.h" +#include "hydro_properties.h" +#include "kick.h" #include "minmax.h" #include "scheduler.h" #include "space.h" #include "task.h" #include "timers.h" +#include "timestep.h" /* Orientation of the cell pairs */ const float runner_shift[13 * 3] = { - 5.773502691896258e-01, 5.773502691896258e-01, 5.773502691896258e-01, - 7.071067811865475e-01, 7.071067811865475e-01, 0.0, - 5.773502691896258e-01, 5.773502691896258e-01, -5.773502691896258e-01, - 7.071067811865475e-01, 0.0, 7.071067811865475e-01, - 1.0, 0.0, 0.0, - 7.071067811865475e-01, 0.0, -7.071067811865475e-01, - 5.773502691896258e-01, -5.773502691896258e-01, 5.773502691896258e-01, - 7.071067811865475e-01, -7.071067811865475e-01, 0.0, - 5.773502691896258e-01, -5.773502691896258e-01, -5.773502691896258e-01, - 0.0, 7.071067811865475e-01, 7.071067811865475e-01, - 0.0, 1.0, 0.0, - 0.0, 7.071067811865475e-01, -7.071067811865475e-01, - 0.0, 0.0, 1.0, }; + 5.773502691896258e-01, + 5.773502691896258e-01, + 5.773502691896258e-01, + 7.071067811865475e-01, + 7.071067811865475e-01, + 0.0, + 5.773502691896258e-01, + 5.773502691896258e-01, + -5.773502691896258e-01, + 7.071067811865475e-01, + 0.0, + 7.071067811865475e-01, + 1.0, + 0.0, + 0.0, + 7.071067811865475e-01, + 0.0, + -7.071067811865475e-01, + 5.773502691896258e-01, + -5.773502691896258e-01, + 5.773502691896258e-01, + 7.071067811865475e-01, + -7.071067811865475e-01, + 0.0, + 5.773502691896258e-01, + -5.773502691896258e-01, + -5.773502691896258e-01, + 0.0, + 7.071067811865475e-01, + 7.071067811865475e-01, + 0.0, + 1.0, + 0.0, + 0.0, + 7.071067811865475e-01, + -7.071067811865475e-01, + 0.0, + 0.0, + 1.0, +}; /* Does the axis need flipping ? */ const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -/* #define MY_CELL 428428428 */ -/* #define DX 0.1 */ -/* #define NX 1000 */ -/* #define CELL_ID \ */ -/* ((int)(c->loc[0] / DX) * NX *NX + (int)(c->loc[1] / DX) * NX + \ */ -/* (int)(c->loc[2] / DX)) */ -/* #define OUT \ */ -/* if (CELL_ID == MY_CELL) { \ */ -/* message(" cell= %d gcount=%d time=%f \n", CELL_ID, c->gcount, - * r->e->time); \ */ -/* } */ -/* #define OUT message(" cell %d %d %f \n",CELL_ID, c->count, r->e->time); */ -/* #define OUT if(CELL_ID == MY_CELL) message("\n cell %f %f %f %d %d */ -/* %f\n",c->loc[0],c->loc[1],c->loc[2], CELL_ID, c->count, r->e->time); */ - /* Import the density loop functions. */ #define FUNCTION density #include "runner_doiact.h" @@ -138,52 +153,6 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) { if (g->ti_end <= ti_current) { external_gravity(potential, constants, g); - - /* /\* check for energy and angular momentum conservation - begin by */ - /* * synchronizing velocity*\/ */ - /* const float dx = g->x[0] - r->e->potential->point_mass.x; */ - /* const float dy = g->x[1] - r->e->potential->point_mass.y; */ - /* const float dz = g->x[2] - r->e->potential->point_mass.z; */ - /* const float dr = sqrtf((dx * dx) + (dy * dy) + (dz * dz)); */ - /* const float rinv = 1.f / sqrtf(dx * dx + dy * dy + dz * dz); */ - - /* const int current_dti = g->ti_end - g->ti_begin; */ - /* const float dt = 0.5f * current_dti * r->e->timeBase; */ - /* const float vx = g->v_full[0] + dt * g->a_grav[0]; */ - /* const float vy = g->v_full[1] + dt * g->a_grav[1]; */ - /* const float vz = g->v_full[2] + dt * g->a_grav[2]; */ - - /* /\* E/L *\/ */ - /* float L[3], E; */ - /* E = 0.5 * ((vx * vx) + (vy * vy) + (vz * vz)) - */ - /* r->e->physical_constants->newton_gravity * */ - /* r->e->potential->point_mass.mass * rinv; */ - /* L[0] = dy * vz - dz * vy; */ - /* L[1] = dz * vx - dx * vz; */ - /* L[2] = dx * vy - dy * vx; */ - /* if (abs(g->id) == 1) { */ - /* float v2 = vx * vx + vy * vy + vz * vz; */ - /* float fg = r->e->physical_constants->newton_gravity * */ - /* r->e->potential->point_mass.mass * rinv; */ - /* float fga = sqrtf((g->a_grav[0] * g->a_grav[0]) + */ - /* (g->a_grav[1] * g->a_grav[1]) + */ - /* (g->a_grav[2] * g->a_grav[2])) * */ - /* dr; */ - /* // message("grav_external time= %f\t V_c^2= %f GM/r= %f E= %f L[2]= - * %f */ - /* // x= %f y= %f vx= %f vy= %f\n", r->e->time, v2, fg, E, L[2], - * g->x[0], */ - /* // g->x[1], vx, vy); */ - /* message("%f\t %f %f %f %f %f %f %f %f %f %f %f %f %f\n", r->e->time, - */ - /* g->tx, g->tv, dt, v2, fg, fga, dr, E, L[2], g->x[0], g->x[1], - */ - /* vx, vy); */ - /* /\* message(" G=%e M=%e\n", r->e->physical_constants->newton_gravity, - */ - /* * r->e->potential->point_mass.mass); *\/ */ - /* /\* exit(-1); *\/ */ - /* } */ } } if (timer) TIMER_TOC(timer_dograv_external); @@ -795,7 +764,12 @@ void runner_do_drift(struct runner *r, struct cell *c, int timer) { struct gpart *const gparts = c->gparts; float dx_max = 0.f, dx2_max = 0.f, h_max = 0.f; + double e_kin = 0.0, e_int = 0.0, e_pot = 0.0, mass = 0.0; + double mom[3] = {0.0, 0.0, 0.0}; + double ang_mom[3] = {0.0, 0.0, 0.0}; + TIMER_TIC + #ifdef TASK_VERBOSE OUT; #endif @@ -811,14 +785,7 @@ void runner_do_drift(struct runner *r, struct cell *c, int timer) { struct gpart *const gp = &gparts[k]; /* Drift... */ - gp->x[0] += gp->v_full[0] * dt; - gp->x[1] += gp->v_full[1] * dt; - gp->x[2] += gp->v_full[2] * dt; - - /* Compute offset since last cell construction */ - gp->x_diff[0] -= gp->v_full[0] * dt; - gp->x_diff[1] -= gp->v_full[1] * dt; - gp->x_diff[2] -= gp->v_full[2] * dt; + drift_gpart(gp, dt, timeBase, ti_old, ti_current); /* Compute (square of) motion since last cell construction */ const float dx2 = gp->x_diff[0] * gp->x_diff[0] + @@ -835,40 +802,8 @@ void runner_do_drift(struct runner *r, struct cell *c, int timer) { struct part *const p = &parts[k]; struct xpart *const xp = &xparts[k]; - /* Useful quantity */ - const float h_inv = 1.0f / p->h; - /* Drift... */ - p->x[0] += xp->v_full[0] * dt; - p->x[1] += xp->v_full[1] * dt; - p->x[2] += xp->v_full[2] * dt; - - /* Predict velocities (for hydro terms) */ - p->v[0] += p->a_hydro[0] * dt; - p->v[1] += p->a_hydro[1] * dt; - p->v[2] += p->a_hydro[2] * dt; - - /* Predict smoothing length */ - const float w1 = p->h_dt * h_inv * dt; - if (fabsf(w1) < 0.2f) - p->h *= approx_expf(w1); /* 4th order expansion of exp(w) */ - else - p->h *= expf(w1); - - /* Predict density */ - const float w2 = -3.0f * p->h_dt * h_inv * dt; - if (fabsf(w2) < 0.2f) - p->rho *= approx_expf(w2); /* 4th order expansion of exp(w) */ - else - p->rho *= expf(w2); - - /* Predict the values of the extra fields */ - hydro_predict_extra(p, xp, ti_old, ti_current, timeBase); - - /* Compute offset since last cell construction */ - xp->x_diff[0] -= xp->v_full[0] * dt; - xp->x_diff[1] -= xp->v_full[1] * dt; - xp->x_diff[2] -= xp->v_full[2] * dt; + drift_part(p, xp, dt, timeBase, ti_old, ti_current); /* Compute (square of) motion since last cell construction */ const float dx2 = xp->x_diff[0] * xp->x_diff[0] + @@ -878,6 +813,34 @@ void runner_do_drift(struct runner *r, struct cell *c, int timer) { /* Maximal smoothing length */ h_max = fmaxf(p->h, h_max); + + /* Now collect quantities for statistics */ + + const float half_dt = + (ti_current - (p->ti_begin + p->ti_end) / 2) * timeBase; + const double x[3] = {p->x[0], p->x[1], p->x[2]}; + const float v[3] = {xp->v_full[0] + p->a_hydro[0] * half_dt, + xp->v_full[1] + p->a_hydro[1] * half_dt, + xp->v_full[2] + p->a_hydro[2] * half_dt}; + const float m = p->mass; + + /* Collect mass */ + mass += m; + + /* Collect momentum */ + mom[0] += m * v[0]; + mom[1] += m * v[1]; + mom[2] += m * v[2]; + + /* Collect angular momentum */ + ang_mom[0] += m * (x[1] * v[2] - x[2] * v[1]); + ang_mom[1] += m * (x[2] * v[0] - x[0] * v[2]); + ang_mom[2] += m * (x[0] * v[1] - x[1] * v[0]); + + /* Collect energies. */ + e_kin += 0.5 * m * (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + e_pot += 0.; + e_int += m * hydro_get_internal_energy(p, half_dt); } /* Now, get the maximal particle motion from its square */ @@ -890,52 +853,64 @@ void runner_do_drift(struct runner *r, struct cell *c, int timer) { /* Loop over the progeny. */ for (int k = 0; k < 8; k++) if (c->progeny[k] != NULL) { + + /* Recurse */ struct cell *cp = c->progeny[k]; runner_do_drift(r, cp, 0); + /* Collect */ dx_max = fmaxf(dx_max, cp->dx_max); h_max = fmaxf(h_max, cp->h_max); + mass += cp->mass; + e_kin += cp->e_kin; + e_int += cp->e_int; + e_pot += cp->e_pot; + mom[0] += cp->mom[0]; + mom[1] += cp->mom[1]; + mom[2] += cp->mom[2]; + ang_mom[0] += cp->ang_mom[0]; + ang_mom[1] += cp->ang_mom[1]; + ang_mom[2] += cp->ang_mom[2]; } } /* Store the values */ c->h_max = h_max; c->dx_max = dx_max; + c->mass = mass; + c->e_kin = e_kin; + c->e_int = e_int; + c->e_pot = e_pot; + c->mom[0] = mom[0]; + c->mom[1] = mom[1]; + c->mom[2] = mom[2]; + c->ang_mom[0] = ang_mom[0]; + c->ang_mom[1] = ang_mom[1]; + c->ang_mom[2] = ang_mom[2]; if (timer) TIMER_TOC(timer_drift); } /** - * @brief Kick particles in momentum space and collect statistics + * @brief Kick particles in momentum space and collect statistics (fixed + * time-step case) * * @param r The runner thread. * @param c The cell. * @param timer Are we timing this ? */ -void runner_do_kick(struct runner *r, struct cell *c, int timer) { +void runner_do_kick_fixdt(struct runner *r, struct cell *c, int timer) { - const float global_dt_min = r->e->dt_min; - const float global_dt_max = r->e->dt_max; - const int ti_current = r->e->ti_current; + const double global_dt = r->e->dt_max; const double timeBase = r->e->timeBase; - const double timeBase_inv = 1.0 / r->e->timeBase; const int count = c->count; const int gcount = c->gcount; struct part *const parts = c->parts; struct xpart *const xparts = c->xparts; struct gpart *const gparts = c->gparts; - const struct external_potential *potential = r->e->external_potential; - const struct hydro_props *hydro_properties = r->e->hydro_properties; - const struct phys_const *constants = r->e->physical_constants; - const float ln_max_h_change = hydro_properties->log_max_h_change; - const int is_fixdt = - (r->e->policy & engine_policy_fixdt) == engine_policy_fixdt; int updated = 0, g_updated = 0; int ti_end_min = max_nr_timesteps, ti_end_max = 0; - double e_kin = 0.0, e_int = 0.0, e_pot = 0.0, mass = 0.0; - float mom[3] = {0.0f, 0.0f, 0.0f}; - float ang[3] = {0.0f, 0.0f, 0.0f}; TIMER_TIC @@ -943,86 +918,143 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { OUT; #endif + /* The new time-step */ + const int new_dti = global_dt / timeBase; + /* No children? */ if (!c->split) { - /* Loop over the g-particles and kick the active ones. */ + /* Loop over the g-particles and kick everyone. */ for (int k = 0; k < gcount; k++) { /* Get a handle on the part. */ struct gpart *const gp = &gparts[k]; - /* If the g-particle has no counterpart and needs to be kicked */ + /* If the g-particle has no counterpart */ if (gp->id < 0) { - if (is_fixdt || gp->ti_end <= ti_current) { + /* First, finish the force calculation */ + gravity_end_force(gp); - /* First, finish the force calculation */ - gravity_end_force(gp); + /* Kick the g-particle forward */ + kick_gpart(gp, new_dti, timeBase); - /* Now we are ready to compute the next time-step size */ - int new_dti; + /* Number of updated g-particles */ + g_updated++; - if (is_fixdt) { + /* Minimal time for next end of time-step */ + ti_end_min = min(gp->ti_end, ti_end_min); + ti_end_max = max(gp->ti_end, ti_end_max); + } + } - /* Now we have a time step, proceed with the kick */ - new_dti = global_dt_max * timeBase_inv; + /* Now do the hydro ones... */ - } else { + /* Loop over the particles and kick everyone. */ + for (int k = 0; k < count; k++) { - /* Compute the next timestep (gravity condition) */ - const float new_dt_external = - gravity_compute_timestep_external(potential, constants, gp); - const float new_dt_self = - gravity_compute_timestep_self(constants, gp); + /* Get a handle on the part. */ + struct part *const p = &parts[k]; + struct xpart *const xp = &xparts[k]; - float new_dt = fminf(new_dt_external, new_dt_self); + /* First, finish the force loop */ + p->h_dt *= p->h * 0.333333333f; - /* Limit timestep within the allowed range */ - new_dt = fminf(new_dt, global_dt_max); - new_dt = fmaxf(new_dt, global_dt_min); + /* And do the same of the extra variable */ + hydro_end_force(p); + if (p->gpart != NULL) gravity_end_force(p->gpart); - /* Convert to integer time */ - new_dti = new_dt * timeBase_inv; + /* Kick the particle forward */ + kick_part(p, xp, new_dti, timeBase); - /* Recover the current timestep */ - const int current_dti = gp->ti_end - gp->ti_begin; + /* Number of updated particles */ + updated++; + if (p->gpart != NULL) g_updated++; - /* Limit timestep increase */ - if (current_dti > 0) new_dti = min(new_dti, 2 * current_dti); + /* Minimal time for next end of time-step */ + ti_end_min = min(p->ti_end, ti_end_min); + ti_end_max = max(p->ti_end, ti_end_max); + } + } - /* Put this timestep on the time line */ - int dti_timeline = max_nr_timesteps; - while (new_dti < dti_timeline) dti_timeline /= 2; + /* Otherwise, aggregate data from children. */ + else { - new_dti = dti_timeline; + /* Loop over the progeny. */ + for (int k = 0; k < 8; k++) + if (c->progeny[k] != NULL) { + struct cell *const cp = c->progeny[k]; - /* Make sure we are allowed to increase the timestep size */ - if (new_dti > current_dti) { - if ((max_nr_timesteps - gp->ti_end) % new_dti > 0) - new_dti = current_dti; - } + /* Recurse */ + runner_do_kick_fixdt(r, cp, 0); - /* Now we have a time step, proceed with the kick */ - } + /* And aggregate */ + updated += cp->updated; + g_updated += cp->g_updated; + ti_end_min = min(cp->ti_end_min, ti_end_min); + ti_end_max = max(cp->ti_end_max, ti_end_max); + } + } - /* Compute the time step for this kick */ - const int ti_start = (gp->ti_begin + gp->ti_end) / 2; - const int ti_end = gp->ti_end + new_dti / 2; - const double dt = (ti_end - ti_start) * timeBase; - const double half_dt = (ti_end - gp->ti_end) * timeBase; + /* Store the values. */ + c->updated = updated; + c->g_updated = g_updated; + c->ti_end_min = ti_end_min; + c->ti_end_max = ti_end_max; - /* Move particle forward in time */ - gp->ti_begin = gp->ti_end; - gp->ti_end = gp->ti_begin + new_dti; + if (timer) TIMER_TOC(timer_kick); +} - /* Kick particles in momentum space */ - gp->v_full[0] += gp->a_grav[0] * dt; - gp->v_full[1] += gp->a_grav[1] * dt; - gp->v_full[2] += gp->a_grav[2] * dt; +/** + * @brief Kick particles in momentum space and collect statistics (floating + * time-step case) + * + * @param r The runner thread. + * @param c The cell. + * @param timer Are we timing this ? + */ +void runner_do_kick(struct runner *r, struct cell *c, int timer) { - /* Extra kick work */ - gravity_kick_extra(gp, dt, half_dt); + const struct engine *e = r->e; + const double timeBase = e->timeBase; + const int ti_current = r->e->ti_current; + const int count = c->count; + const int gcount = c->gcount; + struct part *const parts = c->parts; + struct xpart *const xparts = c->xparts; + struct gpart *const gparts = c->gparts; + + int updated = 0, g_updated = 0; + int ti_end_min = max_nr_timesteps, ti_end_max = 0; + + TIMER_TIC + +#ifdef TASK_VERBOSE + OUT; +#endif + + /* No children? */ + if (!c->split) { + + /* Loop over the g-particles and kick the active ones. */ + for (int k = 0; k < gcount; k++) { + + /* Get a handle on the part. */ + struct gpart *const gp = &gparts[k]; + + /* If the g-particle has no counterpart and needs to be kicked */ + if (gp->id < 0) { + + if (gp->ti_end <= ti_current) { + + /* First, finish the force calculation */ + gravity_end_force(gp); + + /* Compute the next timestep */ + const int new_dti = get_gpart_timestep(gp, e); + + /* Now we have a time step, proceed with the kick */ + kick_gpart(gp, new_dti, timeBase); /* Number of updated g-particles */ g_updated++; @@ -1044,7 +1076,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { struct xpart *const xp = &xparts[k]; /* If particle needs to be kicked */ - if (is_fixdt || p->ti_end <= ti_current) { + if (p->ti_end <= ti_current) { /* First, finish the force loop */ p->h_dt *= p->h * 0.333333333f; @@ -1053,142 +1085,17 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { hydro_end_force(p); if (p->gpart != NULL) gravity_end_force(p->gpart); - /* Now we are ready to compute the next time-step size */ - int new_dti; - - if (is_fixdt) { - - /* Now we have a time step, proceed with the kick */ - new_dti = global_dt_max * timeBase_inv; - - } else { - - /* Compute the next timestep (hydro condition) */ - const float new_dt_hydro = - hydro_compute_timestep(p, xp, hydro_properties); - - /* Compute the next timestep (gravity condition) */ - float new_dt_grav = FLT_MAX; - if (p->gpart != NULL) { - - const float new_dt_external = gravity_compute_timestep_external( - potential, constants, p->gpart); - const float new_dt_self = - gravity_compute_timestep_self(constants, p->gpart); - - new_dt_grav = fminf(new_dt_external, new_dt_self); - } - - /* Final time-step is minimum of hydro and gravity */ - float new_dt = fminf(new_dt_hydro, new_dt_grav); - - /* Limit change in h */ - const float dt_h_change = - (p->h_dt != 0.0f) ? fabsf(ln_max_h_change * p->h / p->h_dt) - : FLT_MAX; - - new_dt = fminf(new_dt, dt_h_change); - - /* Limit timestep within the allowed range */ - new_dt = fminf(new_dt, global_dt_max); - new_dt = fmaxf(new_dt, global_dt_min); + /* Compute the next timestep (hydro condition) */ + const int new_dti = get_part_timestep(p, xp, e); - /* Convert to integer time */ - new_dti = new_dt * timeBase_inv; - - /* Recover the current timestep */ - const int current_dti = p->ti_end - p->ti_begin; - - /* Limit timestep increase */ - if (current_dti > 0) new_dti = min(new_dti, 2 * current_dti); - - /* Put this timestep on the time line */ - int dti_timeline = max_nr_timesteps; - while (new_dti < dti_timeline) dti_timeline /= 2; - - new_dti = dti_timeline; - - /* Make sure we are allowed to increase the timestep size */ - if (new_dti > current_dti) { - if ((max_nr_timesteps - p->ti_end) % new_dti > 0) - new_dti = current_dti; - } - - /* Now we have a time step, proceed with the kick */ - } - - /* Compute the time step for this kick */ - const int ti_start = (p->ti_begin + p->ti_end) / 2; - const int ti_end = p->ti_end + new_dti / 2; - const double dt = (ti_end - ti_start) * timeBase; - const double half_dt = (ti_end - p->ti_end) * timeBase; - - /* Move particle forward in time */ - p->ti_begin = p->ti_end; - p->ti_end = p->ti_begin + new_dti; - if (p->gpart != NULL) { - p->gpart->ti_begin = p->ti_begin; - p->gpart->ti_end = p->ti_end; - } - - /* Get the acceleration */ - float a_tot[3] = {p->a_hydro[0], p->a_hydro[1], p->a_hydro[2]}; - if (p->gpart != NULL) { - a_tot[0] += p->gpart->a_grav[0]; - a_tot[1] += p->gpart->a_grav[1]; - a_tot[1] += p->gpart->a_grav[2]; - } - - /* Kick particles in momentum space */ - xp->v_full[0] += a_tot[0] * dt; - xp->v_full[1] += a_tot[1] * dt; - xp->v_full[2] += a_tot[2] * dt; - - if (p->gpart != NULL) { - p->gpart->v_full[0] = xp->v_full[0]; - p->gpart->v_full[1] = xp->v_full[1]; - p->gpart->v_full[2] = xp->v_full[2]; - } - - /* Go back by half-step for the hydro velocity */ - p->v[0] = xp->v_full[0] - half_dt * a_tot[0]; - p->v[1] = xp->v_full[1] - half_dt * a_tot[1]; - p->v[2] = xp->v_full[2] - half_dt * a_tot[2]; - - /* Extra kick work */ - hydro_kick_extra(p, xp, dt, half_dt); - if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt, half_dt); + /* Now we have a time step, proceed with the kick */ + kick_part(p, xp, new_dti, timeBase); /* Number of updated particles */ updated++; if (p->gpart != NULL) g_updated++; } - /* Now collect quantities for statistics */ - - const double x[3] = {p->x[0], p->x[1], p->x[2]}; - const float v_full[3] = {xp->v_full[0], xp->v_full[1], xp->v_full[2]}; - const float m = p->mass; - - /* Collect mass */ - mass += m; - - /* Collect momentum */ - mom[0] += m * v_full[0]; - mom[1] += m * v_full[1]; - mom[2] += m * v_full[2]; - - /* Collect angular momentum */ - ang[0] += m * (x[1] * v_full[2] - x[2] * v_full[1]); - ang[1] += m * (x[2] * v_full[0] - x[0] * v_full[2]); - ang[2] += m * (x[0] * v_full[1] - x[1] * v_full[0]); - - /* Collect total energy. */ - e_kin += 0.5 * m * (v_full[0] * v_full[0] + v_full[1] * v_full[1] + - v_full[2] * v_full[2]); - e_pot += 0.f; /* No gravitational potential thus far */ - e_int += hydro_get_internal_energy(p); - /* Minimal time for next end of time-step */ ti_end_min = min(p->ti_end, ti_end_min); ti_end_max = max(p->ti_end, ti_end_max); @@ -1209,16 +1116,6 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { /* And aggregate */ updated += cp->updated; g_updated += cp->g_updated; - e_kin += cp->e_kin; - e_int += cp->e_int; - e_pot += cp->e_pot; - mass += cp->mass; - mom[0] += cp->mom[0]; - mom[1] += cp->mom[1]; - mom[2] += cp->mom[2]; - ang[0] += cp->ang[0]; - ang[1] += cp->ang[1]; - ang[2] += cp->ang[2]; ti_end_min = min(cp->ti_end_min, ti_end_min); ti_end_max = max(cp->ti_end_max, ti_end_max); } @@ -1227,16 +1124,6 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { /* Store the values. */ c->updated = updated; c->g_updated = g_updated; - c->e_kin = e_kin; - c->e_int = e_int; - c->e_pot = e_pot; - c->mass = mass; - c->mom[0] = mom[0]; - c->mom[1] = mom[1]; - c->mom[2] = mom[2]; - c->ang[0] = ang[0]; - c->ang[1] = ang[1]; - c->ang[2] = ang[2]; c->ti_end_min = ti_end_min; c->ti_end_max = ti_end_max; @@ -1372,6 +1259,9 @@ void *runner_main(void *data) { case task_type_kick: runner_do_kick(r, ci, 1); break; + case task_type_kick_fixdt: + runner_do_kick_fixdt(r, ci, 1); + break; case task_type_send: break; case task_type_recv: diff --git a/src/runner.h b/src/runner.h index f53822cdbf9608a473fc72e6a2d049cfd6d3c5a2..35e5f56a7b94145eec656b02a1c5568ec39352b6 100644 --- a/src/runner.h +++ b/src/runner.h @@ -51,6 +51,7 @@ void runner_do_ghost(struct runner *r, struct cell *c); void runner_do_sort(struct runner *r, struct cell *c, int flag, int clock); void runner_do_gsort(struct runner *r, struct cell *c, int flag, int clock); void runner_do_kick(struct runner *r, struct cell *c, int timer); +void runner_do_kick_fixdt(struct runner *r, struct cell *c, int timer); void runner_do_drift(struct runner *r, struct cell *c, int timer); void runner_do_init(struct runner *r, struct cell *c, int timer); void *runner_main(void *data); diff --git a/src/scheduler.c b/src/scheduler.c index 1b545aac5a3e4a153f8bbec5824797f7bb0edf60..196031417be11044e46ecb88d7a8e6c6adb0ab66 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -842,7 +842,8 @@ void scheduler_reset(struct scheduler *s, int size) { if (s->tasks_ind != NULL) free(s->tasks_ind); /* Allocate the new lists. */ - if ((s->tasks = (struct task *)malloc(sizeof(struct task) *size)) == NULL || + if ((s->tasks = (struct task *)malloc(sizeof(struct task) * size)) == + NULL || (s->tasks_ind = (int *)malloc(sizeof(int) * size)) == NULL) error("Failed to allocate task lists."); } @@ -1328,7 +1329,7 @@ void scheduler_init(struct scheduler *s, struct space *space, int nr_tasks, /* Init the unlocks. */ if ((s->unlocks = (struct task **)malloc( - sizeof(struct task *) *scheduler_init_nr_unlocks)) == NULL || + sizeof(struct task *) * scheduler_init_nr_unlocks)) == NULL || (s->unlock_ind = (int *)malloc(sizeof(int) * scheduler_init_nr_unlocks)) == NULL) error("Failed to allocate unlocks."); diff --git a/src/scheduler.h b/src/scheduler.h index 754bfb8c224a8b58b6b16e8b5dc71bd6563136f3..7528e13c2f7901ba9979a3ef7567bef1e23d8ac4 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -90,7 +90,7 @@ struct scheduler { volatile int nr_unlocks, size_unlocks, completed_unlock_writes; /* Lock for this scheduler. */ - lock_type lock; + swift_lock_type lock; /* Waiting queue. */ pthread_mutex_t sleep_mutex; diff --git a/src/serial_io.c b/src/serial_io.c index f2c0dcce1cc258e7c9a43027fbdd45e299b47ae6..5abd3ebc28672d68c4135efe5753dc4713c2d3c6 100644 --- a/src/serial_io.c +++ b/src/serial_io.c @@ -608,7 +608,7 @@ void read_ic_serial(char* fileName, double dim[3], struct part** parts, void write_output_serial(struct engine* e, const char* baseName, struct UnitSystem* us, int mpi_rank, int mpi_size, MPI_Comm comm, MPI_Info info) { - hid_t h_file = 0, h_grp = 0, h_grpsph = 0; + hid_t h_file = 0, h_grp = 0; const size_t Ngas = e->s->nr_parts; const size_t Ntot = e->s->nr_gparts; int periodic = e->s->periodic; @@ -710,10 +710,17 @@ void write_output_serial(struct engine* e, const char* baseName, writeCodeDescription(h_file); /* Print the SPH parameters */ - h_grpsph = H5Gcreate(h_file, "/SPH", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - if (h_grpsph < 0) error("Error while creating SPH group"); - writeSPHflavour(h_grpsph); - H5Gclose(h_grpsph); + h_grp = H5Gcreate(h_file, "/SPH", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (h_grp < 0) error("Error while creating SPH group"); + writeSPHflavour(h_grp); + H5Gclose(h_grp); + + /* Print the runtime parameters */ + h_grp = + H5Gcreate(h_file, "/Parameters", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (h_grp < 0) error("Error while creating parameters group"); + parser_write_params_to_hdf5(e->parameter_file, h_grp); + H5Gclose(h_grp); /* Print the system of Units */ writeUnitSystem(h_file, us); diff --git a/src/single_io.c b/src/single_io.c index d545fb086fa4bc63fe58dee2bfe85d9586997850..fb3bf4368feed9892b098228d85c99f0bc3e724b 100644 --- a/src/single_io.c +++ b/src/single_io.c @@ -35,8 +35,8 @@ #include "single_io.h" /* Local includes. */ -#include "const.h" #include "common_io.h" +#include "const.h" #include "error.h" /*----------------------------------------------------------------------------- @@ -562,6 +562,13 @@ void write_output_single(struct engine* e, const char* baseName, writeSPHflavour(h_grp); H5Gclose(h_grp); + /* Print the runtime parameters */ + h_grp = + H5Gcreate(h_file, "/Parameters", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (h_grp < 0) error("Error while creating parameters group"); + parser_write_params_to_hdf5(e->parameter_file, h_grp); + H5Gclose(h_grp); + /* Print the system of Units */ writeUnitSystem(h_file, us); diff --git a/src/space.c b/src/space.c index a36906f6818c6bab0dbef717626fe537289f1715..720961673453433f124f0a4088704224d850d39e 100644 --- a/src/space.c +++ b/src/space.c @@ -28,8 +28,8 @@ #include <float.h> #include <limits.h> #include <math.h> -#include <string.h> #include <stdlib.h> +#include <string.h> /* MPI headers. */ #ifdef WITH_MPI diff --git a/src/space.h b/src/space.h index e70e77f15f0b1ea898fb328746b484a6e61f6738..d448cd1279611c26139672608798089f7c6a7afb 100644 --- a/src/space.h +++ b/src/space.h @@ -97,7 +97,7 @@ struct space { int periodic; /* General-purpose lock for this space. */ - lock_type lock; + swift_lock_type lock; /* Number of queues in the system. */ int nr_queues; diff --git a/src/task.c b/src/task.c index c8f69681c8ac3a142a7fdebd3778eedd5cae546a..4b0b649c63f1af9ceb30a0ff311d55f679a0a503 100644 --- a/src/task.c +++ b/src/task.c @@ -51,8 +51,8 @@ const char *taskID_names[task_type_count] = { "ghost", "drift", "kick", "send", "recv", "grav_pp", "grav_mm", "grav_up", "grav_down", "grav_external", "comm_root"}; -const char *subtaskID_names[task_type_count] = {"none", "density", - "force", "grav"}; +const char *subtaskID_names[task_type_count] = {"none", "density", "force", + "grav"}; /** * @brief Computes the overlap between the parts array of two given cells. diff --git a/src/task.h b/src/task.h index 8193ce970fd67779aa6c8d62e0be5e0b5ea7cd83..a949e02fce1e9e0fa6b86f27e1c192a45b9073f3 100644 --- a/src/task.h +++ b/src/task.h @@ -42,6 +42,7 @@ enum task_types { task_type_ghost, task_type_drift, task_type_kick, + task_type_kick_fixdt, task_type_send, task_type_recv, task_type_grav_pp, @@ -74,7 +75,7 @@ struct task { char skip, tight, implicit; int flags, wait, rank, weight; - lock_type lock; + swift_lock_type lock; struct cell *ci, *cj; diff --git a/src/timestep.h b/src/timestep.h new file mode 100644 index 0000000000000000000000000000000000000000..1674958812d1f9e72eb618a9cb026befd610d06d --- /dev/null +++ b/src/timestep.h @@ -0,0 +1,136 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_TIMESTEP_H +#define SWIFT_TIMESTEP_H + +/* Config parameters. */ +#include "../config.h" + +/* Local headers. */ +#include "const.h" +#include "debug.h" + +/** + * @brief Compute a valid integer time-step form a given time-step + * + * @param new_dt The time-step to convert. + * @param ti_begin The (integer) start of the previous time-step. + * @param ti_end The (integer) end of the previous time-step. + * @param timeBase_inv The inverse of the system's minimal time-step. + */ +__attribute__((always_inline)) INLINE static int get_integer_timestep( + float new_dt, int ti_begin, int ti_end, double timeBase_inv) { + + /* Convert to integer time */ + int new_dti = (int)(new_dt * timeBase_inv); + + /* Recover the current timestep */ + const int current_dti = ti_end - ti_begin; + + /* Limit timestep increase */ + if (current_dti > 0) new_dti = min(new_dti, 2 * current_dti); + + /* Put this timestep on the time line */ + int dti_timeline = max_nr_timesteps; + while (new_dti < dti_timeline) dti_timeline /= 2; + new_dti = dti_timeline; + + /* Make sure we are allowed to increase the timestep size */ + if (new_dti > current_dti) { + if ((max_nr_timesteps - ti_end) % new_dti > 0) new_dti = current_dti; + } + + return new_dti; +} + +/** + * @brief Compute the new (integer) time-step of a given #gpart + * + * @param gp The #gpart. + * @param e The #engine (used to get some constants). + */ +__attribute__((always_inline)) INLINE static int get_gpart_timestep( + const struct gpart *gp, const struct engine *e) { + + const float new_dt_external = gravity_compute_timestep_external( + e->external_potential, e->physical_constants, gp); + const float new_dt_self = + gravity_compute_timestep_self(e->physical_constants, gp); + + float new_dt = fminf(new_dt_external, new_dt_self); + + /* Limit timestep within the allowed range */ + new_dt = fminf(new_dt, e->dt_max); + new_dt = fmaxf(new_dt, e->dt_min); + + /* Convert to integer time */ + const int new_dti = + get_integer_timestep(new_dt, gp->ti_begin, gp->ti_end, e->timeBase_inv); + + return new_dti; +} + +/** + * @brief Compute the new (integer) time-step of a given #part + * + * @param p The #part. + * @param xp The #xpart partner of p. + * @param e The #engine (used to get some constants). + */ +__attribute__((always_inline)) INLINE static int get_part_timestep( + const struct part *p, const struct xpart *xp, const struct engine *e) { + + /* Compute the next timestep (hydro condition) */ + const float new_dt_hydro = hydro_compute_timestep(p, xp, e->hydro_properties); + + /* Compute the next timestep (gravity condition) */ + float new_dt_grav = FLT_MAX; + if (p->gpart != NULL) { + + const float new_dt_external = gravity_compute_timestep_external( + e->external_potential, e->physical_constants, p->gpart); + const float new_dt_self = + gravity_compute_timestep_self(e->physical_constants, p->gpart); + + new_dt_grav = fminf(new_dt_external, new_dt_self); + } + + /* Final time-step is minimum of hydro and gravity */ + float new_dt = fminf(new_dt_hydro, new_dt_grav); + + /* Limit change in h */ + const float dt_h_change = + (p->h_dt != 0.0f) + ? fabsf(e->hydro_properties->log_max_h_change * p->h / p->h_dt) + : FLT_MAX; + + new_dt = fminf(new_dt, dt_h_change); + + /* Limit timestep within the allowed range */ + new_dt = fminf(new_dt, e->dt_max); + new_dt = fmaxf(new_dt, e->dt_min); + + /* Convert to integer time */ + const int new_dti = + get_integer_timestep(new_dt, p->ti_begin, p->ti_end, e->timeBase_inv); + + return new_dti; +} + +#endif /* SWIFT_TIMESTEP_H */ diff --git a/src/tools.c b/src/tools.c index 7b468426b894044dc8e215f5150d9536fa2d4cdd..0363100331ad5b298279e9ebadcf87eab5f9e896 100644 --- a/src/tools.c +++ b/src/tools.c @@ -20,15 +20,15 @@ ******************************************************************************/ #include <math.h> -#include <stdlib.h> #include <stddef.h> #include <stdio.h> +#include <stdlib.h> +#include "cell.h" #include "error.h" #include "part.h" -#include "cell.h" -#include "tools.h" #include "swift.h" +#include "tools.h" /** * Factorize a given integer, attempts to keep larger pair of factors. diff --git a/src/tools.h b/src/tools.h index 8e0212652922fb4afd1ac89a64d4a01c71ecd4a9..5f9f41d033ab03983bde3bb37e87f8a39d2deecd 100644 --- a/src/tools.h +++ b/src/tools.h @@ -22,8 +22,8 @@ #ifndef SWIFT_TOOL_H #define SWIFT_TOOL_H -#include "runner.h" #include "cell.h" +#include "runner.h" void factor(int value, int *f1, int *f2); void density_dump(int N); diff --git a/tests/test27cells.c b/tests/test27cells.c index 504c07b4db391a2bc6fa60b7ec354367008aeec1..3e2f11c7aabac0a7ff2df19f2c48f9f81ea55df5 100644 --- a/tests/test27cells.c +++ b/tests/test27cells.c @@ -18,9 +18,9 @@ ******************************************************************************/ #include <fenv.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <stdio.h> #include <unistd.h> #include "swift.h" @@ -301,7 +301,8 @@ int main(int argc, char *argv[]) { /* Help users... */ message("Smoothing length: h = %f", h * size); message("Kernel: %s", kernel_name); - message("Neighbour target: N = %f", h * h * h * 4.0 * M_PI * kernel_gamma3 / 3.0); + message("Neighbour target: N = %f", + h * h * h * 4.0 * M_PI * kernel_gamma3 / 3.0); message("Density target: rho = %f", rho); message("div_v target: div = %f", vel == 2 ? 3.f : 0.f); message("curl_v target: curl = [0., 0., %f]", vel == 3 ? -2.f : 0.f); diff --git a/tests/testKernel.c b/tests/testKernel.c index 27d45375b91e4143036c32b71a217e80ad630222..182bae5334e1a5061e584212a31186dc4e7f0818 100644 --- a/tests/testKernel.c +++ b/tests/testKernel.c @@ -18,9 +18,9 @@ * ******************************************************************************/ -#define NO__SSE2__ -#include "vector.h" +#define NO__AVX__ #include "kernel_hydro.h" +#include "vector.h" #include <stdlib.h> #include <strings.h> diff --git a/tests/testPair.c b/tests/testPair.c index a70cb381fd9a6dec061a100eeba17bfd54b0e973..f9539fc1a444828c65b39e56618eb7bb98bd67de 100644 --- a/tests/testPair.c +++ b/tests/testPair.c @@ -18,9 +18,9 @@ ******************************************************************************/ #include <fenv.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <stdio.h> #include <unistd.h> #include "swift.h" diff --git a/tests/testParser.c b/tests/testParser.c index 0b08d20c9e2d48de1858877cf186eaa9d0ac84c0..31979a0a572415af04c11063bad9202a0c313426 100644 --- a/tests/testParser.c +++ b/tests/testParser.c @@ -17,11 +17,11 @@ * ******************************************************************************/ -#include "parser.h" #include <assert.h> -#include <string.h> -#include <stdio.h> #include <math.h> +#include <stdio.h> +#include <string.h> +#include "parser.h" int main(int argc, char *argv[]) { const char *input_file = argv[1]; diff --git a/tests/testReading.c b/tests/testReading.c index 33aeb5095ba499bc0fd18ba15b513e351692432e..2fa88855a70a12265f180cd97528dda855322d1d 100644 --- a/tests/testReading.c +++ b/tests/testReading.c @@ -17,9 +17,12 @@ * ******************************************************************************/ -#include "swift.h" +/* Some standard headers. */ #include <stdlib.h> +/* Includes. */ +#include "swift.h" + int main() { size_t Ngas = 0, Ngpart = 0; diff --git a/tests/testSingle.c b/tests/testSingle.c index eb49a570b93b14734c9e6af37d3d8a2b90d04078..d37f20908a28fb2e1098043dd7fbbcf76bd8c247 100644 --- a/tests/testSingle.c +++ b/tests/testSingle.c @@ -22,15 +22,15 @@ #include "../config.h" /* Some standard headers. */ +#include <fenv.h> +#include <float.h> +#include <limits.h> +#include <math.h> +#include <pthread.h> #include <stdio.h> #include <stdlib.h> -#include <unistd.h> #include <string.h> -#include <pthread.h> -#include <math.h> -#include <float.h> -#include <limits.h> -#include <fenv.h> +#include <unistd.h> /* Conditional headers. */ #ifdef HAVE_LIBZ