diff --git a/examples/CosmoVolume/cosmoVolume.yml b/examples/CosmoVolume/cosmoVolume.yml index 56dca668394a0b3d533fd9f7ae466e963c6e4e20..a2f0ad9cccca9f4e7a709545104f199c09363155 100644 --- a/examples/CosmoVolume/cosmoVolume.yml +++ b/examples/CosmoVolume/cosmoVolume.yml @@ -8,16 +8,14 @@ InternalUnitSystem: # Parameters for the task scheduling Scheduler: - nr_queues: 0 # The number of task queues to use. Use 0 to let the system decide. - cell_max_size: 8000000 # Maximal number of interactions per task (this is the default value). - cell_sub_size: 5000 # Maximal number of interactions per sub-task (this is the default value). - cell_split_size: 400 # Maximal number of particles per cell (this is the default value). + cell_sub_size: 6000 # Value used for the original scaling tests + cell_split_size: 300 # Value used for the original scaling tests # 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). - dt_min: 1e-6 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-2 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots @@ -40,23 +38,11 @@ SPH: resolution_eta: 1.2348 # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel). delta_neighbours: 0.1 # The tolerance for the targetted number of neighbours. max_ghost_iterations: 30 # Maximal number of iterations allowed to converge towards the smoothing length. - max_smoothing_length: 0.6 # Maximal smoothing length allowed (in internal units). + max_smoothing_length: 0.705 # Maximal smoothing length allowed (in internal units). CFL_condition: 0.1 # Courant-Friedrich-Levy condition for time integration. max_volume_change: 2. # Maximal allowed change of volume over one time-step # Parameters related to the initial conditions InitialConditions: file_name: ./cosmoVolume.hdf5 # The file to read - h_scaling: 1. # A scaling factor to apply to all smoothing lengths in the ICs. - shift_x: 0. # A shift to apply to all particles read from the ICs (in internal units). - shift_y: 0. - shift_z: 0. -# Parameters govering domain decomposition -DomainDecomposition: - initial_type: m # The initial strategy ("g", "m", "w", or "v"). See documentation for details. - initial_grid_x: 10 # Grid size if the 'g' strategy is chosen. - initial_grid_y: 10 - initial_grid_z: 10 - repartition_type: b # The re-decomposition strategy ("n", "b", "v", "e" or "x"). See documentation for details. - diff --git a/examples/ExternalPointMass/externalPointMass.yml b/examples/ExternalPointMass/externalPointMass.yml index cfc6f0ae6d15a50471900e0bd09113e942fc116d..e4c3abc28362801ee53320f9e547bf6d01670ec7 100644 --- a/examples/ExternalPointMass/externalPointMass.yml +++ b/examples/ExternalPointMass/externalPointMass.yml @@ -6,13 +6,6 @@ InternalUnitSystem: UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin -# Parameters for the task scheduling -Scheduler: - nr_queues: 0 # The number of task queues to use. Use 0 to let the system decide. - cell_max_size: 8000000 # Maximal number of interactions per task (this is the default value). - cell_sub_size: 8000000 # Maximal number of interactions per sub-task (this is the default value). - cell_split_size: 400 # Maximal number of particles per cell (this is the default value). - # Parameters governing the time integration TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). @@ -47,20 +40,10 @@ SPH: # Parameters related to the initial conditions InitialConditions: file_name: Sphere.hdf5 # The file to read - h_scaling: 1. # A scaling factor to apply to all smoothing lengths in the ICs. shift_x: 50. # A shift to apply to all particles read from the ICs (in internal units). shift_y: 50. shift_z: 50. -# Parameters govering domain decomposition -DomainDecomposition: - initial_type: m # The initial strategy ("g", "m", "w", or "v"). See documentation for details. - initial_grid_x: 10 # Grid size if the 'g' strategy is chosen. - initial_grid_y: 10 - initial_grid_z: 10 - repartition_type: b # The re-decomposition strategy ("n", "b", "v", "e" or "x"). See documentation for details. - - # External potential parameters PointMass: position_x: 50. # location of external point mass in internal units diff --git a/examples/SedovBlast/sedov.yml b/examples/SedovBlast/sedov.yml index 1f491c248ffbd590dda5b5dcdf86b3eca27c8ce7..96b16c5b85b2e534e5ac8b7680f61ed9912da3d6 100644 --- a/examples/SedovBlast/sedov.yml +++ b/examples/SedovBlast/sedov.yml @@ -6,13 +6,6 @@ InternalUnitSystem: UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin -# Parameters for the task scheduling -Scheduler: - nr_queues: 0 # The number of task queues to use. Use 0 to let the system decide. - cell_max_size: 8000000 # Maximal number of interactions per task (this is the default value). - cell_sub_size: 5000 # Maximal number of interactions per sub-task (this is the default value). - cell_split_size: 400 # Maximal number of particles per cell (this is the default value). - # Parameters governing the time integration TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). @@ -47,16 +40,4 @@ SPH: # Parameters related to the initial conditions InitialConditions: file_name: ./sedov.hdf5 # The file to read - h_scaling: 1. # A scaling factor to apply to all smoothing lengths in the ICs. - shift_x: 0. # A shift to apply to all particles read from the ICs (in internal units). - shift_y: 0. - shift_z: 0. -# Parameters govering domain decomposition -DomainDecomposition: - initial_type: m # The initial strategy ("g", "m", "w", or "v"). See documentation for details. - initial_grid_x: 10 # Grid size if the 'g' strategy is chosen. - initial_grid_y: 10 - initial_grid_z: 10 - repartition_type: b # The re-decomposition strategy ("n", "b", "v", "e" or "x"). See documentation for details. - diff --git a/examples/SodShock/sodShock.yml b/examples/SodShock/sodShock.yml index d61c593f10387ad1a6bfc9cbbe9e89f05f84c52c..62ed0c68cad8e063f49ab0655aee0e10f57e6314 100644 --- a/examples/SodShock/sodShock.yml +++ b/examples/SodShock/sodShock.yml @@ -6,13 +6,6 @@ InternalUnitSystem: UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin -# Parameters for the task scheduling -Scheduler: - nr_queues: 0 # The number of task queues to use. Use 0 to let the system decide. - cell_max_size: 8000000 # Maximal number of interactions per task (this is the default value). - cell_sub_size: 5000 # Maximal number of interactions per sub-task. - cell_split_size: 400 # Maximal number of particles per cell (this is the default value). - # Parameters governing the time integration TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). @@ -47,16 +40,4 @@ SPH: # Parameters related to the initial conditions InitialConditions: file_name: ./sodShock.hdf5 # The file to read - h_scaling: 1. # A scaling factor to apply to all smoothing lengths in the ICs. - shift_x: 0. # A shift to apply to all particles read from the ICs (in internal units). - shift_y: 0. - shift_z: 0. -# Parameters govering domain decomposition -DomainDecomposition: - initial_type: m # The initial strategy ("g", "m", "w", or "v"). See documentation for details. - initial_grid_x: 10 # Grid size if the 'g' strategy is chosen. - initial_grid_y: 10 - initial_grid_z: 10 - repartition_type: b # The re-decomposition strategy ("n", "b", "v", "e" or "x"). See documentation for details. - diff --git a/examples/UniformBox/uniformBox.yml b/examples/UniformBox/uniformBox.yml index 15d956a5d752262db91208f689005a7dc85f30d5..64f9a135fff6ecb2e4500ade95d1500a0712f2c8 100644 --- a/examples/UniformBox/uniformBox.yml +++ b/examples/UniformBox/uniformBox.yml @@ -6,13 +6,6 @@ InternalUnitSystem: UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin -# Parameters for the task scheduling -Scheduler: - nr_queues: 0 # The number of task queues to use. Use 0 to let the system decide. - cell_max_size: 8000000 # Maximal number of interactions per task (this is the default value). - cell_sub_size: 5000 # Maximal number of interactions per sub-task (this is the default value). - cell_split_size: 400 # Maximal number of particles per cell (this is the default value). - # Parameters governing the time integration TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). @@ -47,16 +40,3 @@ SPH: # Parameters related to the initial conditions InitialConditions: file_name: ./uniformBox.hdf5 # The file to read - h_scaling: 1. # A scaling factor to apply to all smoothing lengths in the ICs. - shift_x: 0. # A shift to apply to all particles read from the ICs (in internal units). - shift_y: 0. - shift_z: 0. - -# Parameters govering domain decomposition -DomainDecomposition: - initial_type: m # The initial strategy ("g", "m", "w", or "v"). See documentation for details. - initial_grid_x: 10 # Grid size if the 'g' strategy is chosen. - initial_grid_y: 10 - initial_grid_z: 10 - repartition_type: b # The re-decomposition strategy ("n", "b", "v", "e" or "x"). See documentation for details. - diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index b3b9b52ad73fad2bde9b40b983f88acc3e985fbb..9b2ebd028a3506e231aa36ed2078bb44faf4eb49 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -8,10 +8,10 @@ InternalUnitSystem: # Parameters for the task scheduling Scheduler: - nr_queues: 0 # The number of task queues to use. Use 0 to let the system decide. - cell_max_size: 8000000 # Maximal number of interactions per task (this is the default value). - cell_sub_size: 8000000 # Maximal number of interactions per sub-task (this is the default value). - cell_split_size: 400 # Maximal number of particles per cell (this is the default value). + nr_queues: 0 # (Optional) The number of task queues to use. Use 0 to let the system decide. + cell_max_size: 8000000 # (Optional) Maximal number of interactions per task (this is the default value). + cell_sub_size: 8000000 # (Optional) Maximal number of interactions per sub-task (this is the default value). + cell_split_size: 400 # (Optional) Maximal number of particles per cell (this is the default value). # Parameters governing the time integration TimeIntegration: @@ -42,23 +42,23 @@ SPH: max_ghost_iterations: 30 # Maximal number of iterations allowed to converge towards the smoothing length. max_smoothing_length: 0.1 # Maximal smoothing length allowed (in internal units). CFL_condition: 0.1 # Courant-Friedrich-Levy condition for time integration. - max_volume_change: 2. # Maximal allowed change of volume over one time-step + max_volume_change: 2. # Maximal allowed change of kernel volume over one time-step # Parameters related to the initial conditions InitialConditions: file_name: SedovBlast/sedov.hdf5 # The file to read - h_scaling: 1. # A scaling factor to apply to all smoothing lengths in the ICs. - shift_x: 0. # A shift to apply to all particles read from the ICs (in internal units). + h_scaling: 1. # (Optional) A scaling factor to apply to all smoothing lengths in the ICs. + shift_x: 0. # (Optional) A shift to apply to all particles read from the ICs (in internal units). shift_y: 0. shift_z: 0. # Parameters govering domain decomposition DomainDecomposition: - initial_type: m # The initial strategy ("g", "m", "w", or "v"). See documentation for details. - initial_grid_x: 10 # Grid size if the 'g' strategy is chosen. + initial_type: m # (Optional) The initial strategy ("g", "m", "w", or "v"). + initial_grid_x: 10 # (Optional) Grid size if the "g" strategy is chosen. initial_grid_y: 10 initial_grid_z: 10 - repartition_type: b # The re-decomposition strategy ("n", "b", "v", "e" or "x"). See documentation for details. + repartition_type: b # (Optional) The re-decomposition strategy ("n", "b", "v", "e" or "x"). # Parameters related to external potentials diff --git a/examples/runs_mpi_cv.sh b/examples/runs_mpi_cv.sh deleted file mode 100755 index a808d9c45afa952669327a793f1f5d7579ced74b..0000000000000000000000000000000000000000 --- a/examples/runs_mpi_cv.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash - -# Set the number of runs -FINALTIME=1. - -# Cores per node -CPN=12 - -# The queue on which to run -QUEUE=cosma -PROJECT=durham -PREFIX=CosmoVolume -INPUT=$PREFIX/CosmoVolume.hdf5 - -# Make sure the OMP threads don't go wild -export OMP_WAIT_POLICY=PASSIVE - -# Set the library path so that libmetis is found -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/cosma/home/nnrw56/lib - -# Single-node runs -for cpu in $(seq 1 $CPN) -do - if [ ! -e ${PREFIX}_${QUEUE}_1x${cpu}.dump ] - then - bsub -oo ${PREFIX}_${QUEUE}_1x${cpu}.dump -q ${QUEUE} -P ${PROJECT} -x -n 1 -R "span[ptile=1]" ./swift -c $FINALTIME -t $cpu -f ${INPUT} -m 0.705 -w 6000 -z 300 -d 1e-7 -e 0.01 - fi -done - -# Multi-node runs -if [ ! -e ${PREFIX}_${QUEUE}_2x${cpu}.dump ] -then - bsub -oo ${PREFIX}_${QUEUE}_2x${CPN}.dump -q ${QUEUE} -P ${PROJECT} -x -W 02:00 -n 2 -R "span[ptile=1]" mpirun -np 2 ./swift_mpi -c $FINALTIME -t $CPN -g "2 1 1" -f ${INPUT} -m 0.705 -w 6000 -z 300 -d 1e-7 -e 0.01 -fi - -if [ ! -e ${PREFIX}_${QUEUE}_4x${cpu}.dump ] -then - bsub -oo ${PREFIX}_${QUEUE}_4x${CPN}.dump -q ${QUEUE} -P ${PROJECT} -x -W 02:00 -n 4 -R "span[ptile=1]" mpirun -np 4 ./swift_mpi -c $FINALTIME -t $CPN -g "2 2 1" -f ${INPUT} -m 0.705 -w 6000 -z 300 -d 1e-7 -e 0.01 -fi - -if [ ! -e ${PREFIX}_${QUEUE}_8x${cpu}.dump ] -then - bsub -oo ${PREFIX}_${QUEUE}_8x${CPN}.dump -q ${QUEUE} -P ${PROJECT} -x -W 02:00 -n 8 -R "span[ptile=1]" mpirun -np 8 ./swift_mpi -c $FINALTIME -t $CPN -g "2 2 2" -f ${INPUT} -m 0.705 -w 6000 -z 300 -d 1e-7 -e 0.01 -fi - -if [ ! -e ${PREFIX}_${QUEUE}_16x${cpu}.dump ] -then - bsub -oo ${PREFIX}_${QUEUE}_16x${CPN}.dump -q ${QUEUE} -P ${PROJECT} -x -W 02:00 -n 16 -R "span[ptile=1]" mpirun -np 16 ./swift_mpi -c $FINALTIME -t $CPN -g "4 2 2" -f ${INPUT} -m 0.705 -w 6000 -z 300 -d 1e-7 -e 0.01 -fi - -if [ ! -e ${PREFIX}_${QUEUE}_32x${cpu}.dump ] -then - bsub -oo ${PREFIX}_${QUEUE}_32x${CPN}.dump -q ${QUEUE} -P ${PROJECT} -x -W 02:00 -n 32 -R "span[ptile=1]" mpirun -np 32 ./swift_mpi -c $FINALTIME -t $CPN -g "4 4 2" -f ${INPUT} -m 0.705 -w 6000 -z 300 -d 1e-7 -e 0.01 -fi - -if [ ! -e ${PREFIX}_${QUEUE}_64x${cpu}.dump ] -then - bsub -oo ${PREFIX}_${QUEUE}_64x${CPN}.dump -q ${QUEUE} -P ${PROJECT} -x -W 02:00 -n 64 -R "span[ptile=1]" mpirun -np 64 ./swift_mpi -c $FINALTIME -t $CPN -g "4 4 4" -f ${INPUT} -m 0.705 -w 6000 -z 300 -d 1e-7 -e 0.01 -fi - -if [ ! -e ${PREFIX}_${QUEUE}_128x${cpu}.dump ] -then - bsub -oo ${PREFIX}_${QUEUE}_128x${CPN}.dump -q ${QUEUE} -P ${PROJECT} -x -W 02:00 -n 128 -R "span[ptile=1]" mpirun -np 128 ./swift_mpi -c $FINALTIME -t $CPN -g "8 4 4" -f ${INPUT} -m 0.705 -w 6000 -z 300 -d 1e-7 -e 0.01 -fi - diff --git a/src/engine.c b/src/engine.c index 733e5e787357289afcf68dcddef3b0ae286d2ce3..c76bdbd48fc3c65300da868f596c099803437892 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2634,8 +2634,11 @@ void engine_init(struct engine *e, struct space *s, s->e = e; /* Get the number of queues */ - int nr_queues = parser_get_param_int(params, "Scheduler:nr_queues"); + int nr_queues = + parser_get_opt_param_int(params, "Scheduler:nr_queues", nr_threads); if (nr_queues <= 0) nr_queues = e->nr_threads; + if (nr_queues != nr_threads) + message("Number of task queues set to %d", nr_queues); s->nr_queues = nr_queues; /* Deal with affinity. For now, just figure out the number of cores. */ diff --git a/src/parser.c b/src/parser.c index 74c277f036c733b5b1fbff4f2cb477b52169e2c6..32377f877dc1796ec8bf38ae4de2e9c71b219509 100644 --- a/src/parser.c +++ b/src/parser.c @@ -158,7 +158,6 @@ static int is_empty(const char *str) { static void find_duplicate_params(const struct swift_params *params, const char *param_name) { for (int i = 0; i < params->paramCount; i++) { - /*strcmp returns 0 if both strings are the same.*/ if (!strcmp(param_name, params->data[i].name)) { error("Invalid line:%d '%s', parameter is a duplicate.", lineNumber, param_name); @@ -176,7 +175,6 @@ static void find_duplicate_params(const struct swift_params *params, static void find_duplicate_section(const struct swift_params *params, const char *section_name) { for (int i = 0; i < params->sectionCount; i++) { - /*strcmp returns 0 if both strings are the same.*/ if (!strcmp(section_name, params->section[i].name)) { error("Invalid line:%d '%s', section is a duplicate.", lineNumber, section_name); @@ -212,7 +210,6 @@ static void parse_line(char *line, struct swift_params *params) { parse_value(trim_line, params); } /* Check for invalid lines,not including the start and end of file. */ - /* Note: strcmp returns 0 if both strings are the same.*/ else if (strcmp(trim_line, PARSER_START_OF_FILE) && strcmp(trim_line, PARSER_END_OF_FILE)) { error("Invalid line:%d '%s'.", lineNumber, trim_line); @@ -381,7 +378,6 @@ int parser_get_param_int(const struct swift_params *params, const char *name) { int retParam = 0; for (int i = 0; i < params->paramCount; i++) { - /*strcmp returns 0 if both strings are the same.*/ if (!strcmp(name, params->data[i].name)) { /* Check that exactly one number is parsed. */ if (sscanf(params->data[i].value, "%d%s", &retParam, str) != 1) { @@ -414,7 +410,6 @@ char parser_get_param_char(const struct swift_params *params, char retParam = 0; for (int i = 0; i < params->paramCount; i++) { - /*strcmp returns 0 if both strings are the same.*/ if (!strcmp(name, params->data[i].name)) { /* Check that exactly one number is parsed. */ if (sscanf(params->data[i].value, "%c%s", &retParam, str) != 1) { @@ -447,7 +442,6 @@ float parser_get_param_float(const struct swift_params *params, float retParam = 0.f; for (int i = 0; i < params->paramCount; i++) { - /*strcmp returns 0 if both strings are the same.*/ if (!strcmp(name, params->data[i].name)) { /* Check that exactly one number is parsed. */ if (sscanf(params->data[i].value, "%f%s", &retParam, str) != 1) { @@ -480,7 +474,6 @@ double parser_get_param_double(const struct swift_params *params, double retParam = 0.; for (int i = 0; i < params->paramCount; i++) { - /*strcmp returns 0 if both strings are the same.*/ if (!strcmp(name, params->data[i].name)) { /* Check that exactly one number is parsed. */ if (sscanf(params->data[i].value, "%lf%s", &retParam, str) != 1) { @@ -508,7 +501,6 @@ 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) { for (int i = 0; i < params->paramCount; i++) { - /*strcmp returns 0 if both strings are the same.*/ if (!strcmp(name, params->data[i].name)) { strcpy(retParam, params->data[i].value); return; @@ -518,6 +510,150 @@ void parser_get_param_string(const struct swift_params *params, error("Cannot find '%s' in the structure.", name); } +/** + * @brief Retrieve optional integer parameter from structure. + * + * @param params Structure that holds the parameters + * @param name Name of the parameter to be found + * @param def Default value of the parameter of not found. + * @return Value of the parameter found + */ +int parser_get_opt_param_int(const struct swift_params *params, + const char *name, int def) { + + char str[PARSER_MAX_LINE_SIZE]; + int retParam = 0; + + for (int i = 0; i < params->paramCount; i++) { + if (!strcmp(name, params->data[i].name)) { + /* Check that exactly one number is parsed. */ + if (sscanf(params->data[i].value, "%d%s", &retParam, str) != 1) { + error( + "Tried parsing int '%s' but found '%s' with illegal integer " + "characters '%s'.", + params->data[i].name, params->data[i].value, str); + } + + return retParam; + } + } + + return def; +} + +/** + * @brief Retrieve optional char parameter from structure. + * + * @param params Structure that holds the parameters + * @param name Name of the parameter to be found + * @param def Default value of the parameter of not found. + * @return Value of the parameter found + */ +char parser_get_opt_param_char(const struct swift_params *params, + const char *name, char def) { + + char str[PARSER_MAX_LINE_SIZE]; + char retParam = 0; + + for (int i = 0; i < params->paramCount; i++) { + if (!strcmp(name, params->data[i].name)) { + /* Check that exactly one number is parsed. */ + if (sscanf(params->data[i].value, "%c%s", &retParam, str) != 1) { + error( + "Tried parsing char '%s' but found '%s' with illegal char " + "characters '%s'.", + params->data[i].name, params->data[i].value, str); + } + + return retParam; + } + } + + return def; +} + +/** + * @brief Retrieve optional float parameter from structure. + * + * @param params Structure that holds the parameters + * @param name Name of the parameter to be found + * @param def Default value of the parameter of not found. + * @return Value of the parameter found + */ +float parser_get_opt_param_float(const struct swift_params *params, + const char *name, float def) { + + char str[PARSER_MAX_LINE_SIZE]; + float retParam = 0.f; + + for (int i = 0; i < params->paramCount; i++) { + if (!strcmp(name, params->data[i].name)) { + /* Check that exactly one number is parsed. */ + if (sscanf(params->data[i].value, "%f%s", &retParam, str) != 1) { + error( + "Tried parsing float '%s' but found '%s' with illegal float " + "characters '%s'.", + params->data[i].name, params->data[i].value, str); + } + + return retParam; + } + } + + return def; +} + +/** + * @brief Retrieve optional double parameter from structure. + * + * @param params Structure that holds the parameters + * @param name Name of the parameter to be found + * @param def Default value of the parameter of not found. + * @return Value of the parameter found + */ +double parser_get_opt_param_double(const struct swift_params *params, + const char *name, double def) { + + char str[PARSER_MAX_LINE_SIZE]; + double retParam = 0.; + + for (int i = 0; i < params->paramCount; i++) { + if (!strcmp(name, params->data[i].name)) { + /* Check that exactly one number is parsed. */ + if (sscanf(params->data[i].value, "%lf%s", &retParam, str) != 1) { + error( + "Tried parsing double '%s' but found '%s' with illegal double " + "characters '%s'.", + params->data[i].name, params->data[i].value, str); + } + return retParam; + } + } + + return def; +} + +/** + * @brief Retrieve string parameter from structure. + * + * @param params Structure that holds the parameters + * @param name Name of the parameter to be found + * @param def Default value of the parameter of not found. + * @param retParam (return) Value of the parameter found + */ +void parser_get_opt_param_string(const struct swift_params *params, + const char *name, char *retParam, + const char *def) { + for (int i = 0; i < params->paramCount; i++) { + if (!strcmp(name, params->data[i].name)) { + strcpy(retParam, params->data[i].value); + return; + } + } + + strcpy(retParam, def); +} + /** * @brief Prints the contents of the parameter structure. * diff --git a/src/parser.h b/src/parser.h index 21156a37b3bc76d8c3ba01385cb991b2fe213a85..b78e21194d256ed7b50b8a09718c9725d52a1e0b 100644 --- a/src/parser.h +++ b/src/parser.h @@ -55,6 +55,7 @@ void parser_read_file(const char *file_name, struct swift_params *params); void parser_print_params(const struct swift_params *params); void parser_write_params_to_file(const struct swift_params *params, const char *file_name); + char parser_get_param_char(const struct swift_params *params, const char *name); int parser_get_param_int(const struct swift_params *params, const char *name); float parser_get_param_float(const struct swift_params *params, @@ -64,6 +65,18 @@ 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); +char parser_get_opt_param_char(const struct swift_params *params, + const char *name, char def); +int parser_get_opt_param_int(const struct swift_params *params, + const char *name, int def); +float parser_get_opt_param_float(const struct swift_params *params, + const char *name, float def); +double parser_get_opt_param_double(const struct swift_params *params, + const char *name, double def); +void parser_get_opt_param_string(const struct swift_params *params, + const char *name, char *retParam, + const char *def); + #if defined(HAVE_HDF5) void parser_write_params_to_hdf5(const struct swift_params *params, hid_t grp); #endif diff --git a/src/partition.c b/src/partition.c index 432943f05f78b41086c7d0d9cc29b1456f094d54..aa3ee8724ad4b063a7b64ad6ab2ba968a00f9787 100644 --- a/src/partition.c +++ b/src/partition.c @@ -922,11 +922,11 @@ void partition_init(struct partition *partition, /* Defaults make use of METIS if available */ #ifdef HAVE_METIS - *reparttype = REPART_METIS_BOTH; - partition->type = INITPART_METIS_NOWEIGHT; + char default_repart = 'b';; + char default_part = 'm'; #else - *reparttype = REPART_NONE; - partition->type = INITPART_GRID; + char default_repart = 'n'; + char default_part = 'g'; #endif /* Set a default grid so that grid[0]*grid[1]*grid[2] == nr_nodes. */ @@ -936,9 +936,10 @@ void partition_init(struct partition *partition, factor(partition->grid[0] * partition->grid[1], &partition->grid[1], &partition->grid[0]); - /* Now let's check what the user wants as an initial domain*/ + /* Now let's check what the user wants as an initial domain. */ const char part_type = - parser_get_param_char(params, "DomainDecomposition:initial_type"); + parser_get_opt_param_char(params, "DomainDecomposition:initial_type", + default_part); switch (part_type) { case 'g': @@ -967,16 +968,21 @@ void partition_init(struct partition *partition, /* In case of grid, read more parameters */ if (part_type == 'g') { partition->grid[0] = - parser_get_param_int(params, "DomainDecomposition:initial_grid_x"); + parser_get_opt_param_int(params, "DomainDecomposition:initial_grid_x", + partition->grid[0]); partition->grid[1] = - parser_get_param_int(params, "DomainDecomposition:initial_grid_y"); + parser_get_opt_param_int(params, "DomainDecomposition:initial_grid_y", + partition->grid[1]); partition->grid[2] = - parser_get_param_int(params, "DomainDecomposition:initial_grid_z"); + parser_get_opt_param_int(params, "DomainDecomposition:initial_grid_z", + partition->grid[2]); } /* Now let's check what the user wants as a repartition strategy */ const char repart_type = - parser_get_param_char(params, "DomainDecomposition:repartition_type"); + parser_get_opt_param_char(params, + "DomainDecomposition:repartition_type", + default_repart); switch (repart_type) { case 'n': diff --git a/src/space.c b/src/space.c index ffb39dcf51cefc1b3bfc6d2ce8f3f3af972eb6d5..0af5009c9a33ac63851a479b82afca355186faac 100644 --- a/src/space.c +++ b/src/space.c @@ -1437,9 +1437,12 @@ void space_init(struct space *s, const struct swift_params *params, s->size_parts_foreign = 0; /* Get the constants for the scheduler */ - space_maxsize = parser_get_param_int(params, "Scheduler:cell_max_size"); - space_subsize = parser_get_param_int(params, "Scheduler:cell_sub_size"); - space_splitsize = parser_get_param_int(params, "Scheduler:cell_split_size"); + space_maxsize = parser_get_opt_param_int(params, "Scheduler:cell_max_size", + space_maxsize_default); + space_subsize = parser_get_opt_param_int(params, "Scheduler:cell_sub_size", + space_subsize_default); + space_splitsize = parser_get_opt_param_int( + params, "Scheduler:cell_split_size", space_splitsize_default); if (verbose) message("max_size set to %d, sub_size set to %d, split_size set to %d", space_maxsize, space_subsize, space_splitsize); @@ -1454,7 +1457,7 @@ void space_init(struct space *s, const struct swift_params *params, /* Apply h scaling */ const double scaling = - parser_get_param_double(params, "InitialConditions:h_scaling"); + parser_get_opt_param_double(params, "InitialConditions:h_scaling", 1.0); if (scaling != 1.0 && !dry_run) { message("Re-scaling smoothing lengths by a factor %e", scaling); for (size_t k = 0; k < Npart; k++) parts[k].h *= scaling; @@ -1462,10 +1465,13 @@ void space_init(struct space *s, const struct swift_params *params, /* Apply shift */ double shift[3] = {0.0, 0.0, 0.0}; - shift[0] = parser_get_param_double(params, "InitialConditions:shift_x"); - shift[1] = parser_get_param_double(params, "InitialConditions:shift_y"); - shift[2] = parser_get_param_double(params, "InitialConditions:shift_z"); - if ((shift[0] != 0 || shift[1] != 0 || shift[2] != 0) && !dry_run) { + shift[0] = + parser_get_opt_param_double(params, "InitialConditions:shift_x", 0.0); + shift[1] = + parser_get_opt_param_double(params, "InitialConditions:shift_y", 0.0); + shift[2] = + parser_get_opt_param_double(params, "InitialConditions:shift_z", 0.0); + if ((shift[0] != 0. || shift[1] != 0. || shift[2] != 0.) && !dry_run) { message("Shifting particles by [%e %e %e]", shift[0], shift[1], shift[2]); for (size_t k = 0; k < Npart; k++) { parts[k].x[0] += shift[0]; diff --git a/tests/testParser.c b/tests/testParser.c index 31979a0a572415af04c11063bad9202a0c313426..f1211199924df728dfe57376781dc07fe862cec7 100644 --- a/tests/testParser.c +++ b/tests/testParser.c @@ -50,14 +50,17 @@ int main(int argc, char *argv[]) { parser_get_param_double(¶m_file, "Simulation:start_time"); const int kernel = parser_get_param_int(¶m_file, "kernel"); + const int optional = parser_get_opt_param_int(¶m_file, "optional", 1); + char ic_file[PARSER_MAX_LINE_SIZE]; parser_get_param_string(¶m_file, "IO:ic_file", ic_file); /* Print the variables to check their values are correct. */ printf( "no_of_threads: %d, no_of_time_steps: %d, max_h: %f, start_time: %lf, " - "ic_file: %s, kernel: %d\n", - no_of_threads, no_of_time_steps, max_h, start_time, ic_file, kernel); + "ic_file: %s, kernel: %d optional: %d\n", + no_of_threads, no_of_time_steps, max_h, start_time, ic_file, kernel, + optional); assert(no_of_threads == 16); assert(no_of_time_steps == 10); @@ -65,6 +68,7 @@ int main(int argc, char *argv[]) { assert(fabs(start_time - 1.23456789) < 0.00001); assert(strcmp(ic_file, "ic_file.ini") == 0); /*strcmp returns 0 if correct.*/ assert(kernel == 4); + assert(optional == 1); return 0; }