From 5167918e108530201fd3bc6232a5f00a63a7153e Mon Sep 17 00:00:00 2001 From: Menno Fraters Date: Thu, 13 Jun 2024 13:24:34 -0400 Subject: [PATCH] Move particle plugin declarations to relative path instead of absolulte path. --- source/particle/generator/ascii_file.cc | 48 +-- source/particle/generator/interface.cc | 26 +- .../generator/probability_density_function.cc | 108 +++-- source/particle/generator/random_uniform.cc | 78 ++-- source/particle/generator/reference_cell.cc | 48 +-- source/particle/generator/uniform_box.cc | 100 +++-- source/particle/generator/uniform_radial.cc | 162 ++++---- source/particle/integrator/interface.cc | 144 +++---- source/particle/integrator/rk_2.cc | 32 +- .../interpolator/bilinear_least_squares.cc | 153 ++++--- source/particle/interpolator/cell_average.cc | 22 +- .../particle/interpolator/harmonic_average.cc | 22 +- source/particle/interpolator/interface.cc | 26 +- .../particle/interpolator/nearest_neighbor.cc | 22 +- .../interpolator/quadratic_least_squares.cc | 154 ++++--- .../particle/property/cpo_bingham_average.cc | 57 ++- .../particle/property/cpo_elastic_tensor.cc | 14 +- .../property/crystal_preferred_orientation.cc | 388 +++++++++--------- source/particle/property/function.cc | 50 +-- source/particle/property/interface.cc | 99 ++--- source/particle/property/melt_particle.cc | 24 +- source/particle/world.cc | 67 +-- unit_tests/crystal_preferred_orientation.cc | 51 ++- unit_tests/particles.cc | 7 +- 24 files changed, 883 insertions(+), 1019 deletions(-) diff --git a/source/particle/generator/ascii_file.cc b/source/particle/generator/ascii_file.cc index 2bad70de001..539c55f496f 100644 --- a/source/particle/generator/ascii_file.cc +++ b/source/particle/generator/ascii_file.cc @@ -61,31 +61,27 @@ namespace aspect void AsciiFile::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Ascii file"); { - prm.enter_subsection("Ascii file"); - { - prm.declare_entry ("Data directory", - "$ASPECT_SOURCE_DIR/data/particle/generator/ascii/", - Patterns::DirectoryName (), - "The name of a directory that contains the particle data. This path " - "may either be absolute (if starting with a '/') or relative to " - "the current directory. The path may also include the special " - "text '$ASPECT_SOURCE_DIR' which will be interpreted as the path " - "in which the ASPECT source files were located when ASPECT was " - "compiled. This interpretation allows, for example, to reference " - "files located in the `data/' subdirectory of ASPECT. "); - prm.declare_entry ("Data file name", "particle.dat", - Patterns::Anything (), - "The name of the particle file."); - prm.leave_subsection(); - } - prm.leave_subsection(); + prm.declare_entry ("Data directory", + "$ASPECT_SOURCE_DIR/data/particle/generator/ascii/", + Patterns::DirectoryName (), + "The name of a directory that contains the particle data. This path " + "may either be absolute (if starting with a '/') or relative to " + "the current directory. The path may also include the special " + "text '$ASPECT_SOURCE_DIR' which will be interpreted as the path " + "in which the ASPECT source files were located when ASPECT was " + "compiled. This interpretation allows, for example, to reference " + "files located in the `data/' subdirectory of ASPECT. "); + prm.declare_entry ("Data file name", "particle.dat", + Patterns::Anything (), + "The name of the particle file."); } prm.leave_subsection(); } + prm.leave_subsection(); } @@ -93,17 +89,13 @@ namespace aspect void AsciiFile::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Ascii file"); { - prm.enter_subsection("Ascii file"); - { - data_directory = Utilities::expand_ASPECT_SOURCE_DIR(prm.get ("Data directory")); + data_directory = Utilities::expand_ASPECT_SOURCE_DIR(prm.get ("Data directory")); - data_filename = prm.get ("Data file name"); - } - prm.leave_subsection(); + data_filename = prm.get ("Data file name"); } prm.leave_subsection(); } diff --git a/source/particle/generator/interface.cc b/source/particle/generator/interface.cc index 08080613a16..f48c36c2525 100644 --- a/source/particle/generator/interface.cc +++ b/source/particle/generator/interface.cc @@ -218,11 +218,7 @@ namespace aspect create_particle_generator (ParameterHandler &prm) { std::string name; - prm.enter_subsection ("Particles"); - { - name = prm.get ("Particle generator name"); - } - prm.leave_subsection (); + name = prm.get ("Particle generator name"); return std::get(registered_plugins).create_plugin (name, "Particle::Generator name"); @@ -235,18 +231,14 @@ namespace aspect declare_parameters (ParameterHandler &prm) { // declare the entry in the parameter file - prm.enter_subsection ("Particles"); - { - const std::string pattern_of_names - = std::get(registered_plugins).get_pattern_of_names (); - - prm.declare_entry ("Particle generator name", "random uniform", - Patterns::Selection (pattern_of_names), - "Select one of the following models:\n\n" - + - std::get(registered_plugins).get_description_string()); - } - prm.leave_subsection (); + const std::string pattern_of_names + = std::get(registered_plugins).get_pattern_of_names (); + + prm.declare_entry ("Particle generator name", "random uniform", + Patterns::Selection (pattern_of_names), + "Select one of the following models:\n\n" + + + std::get(registered_plugins).get_description_string()); std::get(registered_plugins).declare_parameters (prm); } diff --git a/source/particle/generator/probability_density_function.cc b/source/particle/generator/probability_density_function.cc index a518916b7a3..d276fd2399e 100644 --- a/source/particle/generator/probability_density_function.cc +++ b/source/particle/generator/probability_density_function.cc @@ -49,44 +49,40 @@ namespace aspect void ProbabilityDensityFunction::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Probability density function"); { - prm.enter_subsection("Probability density function"); - { - Functions::ParsedFunction::declare_parameters (prm, 1); - - prm.declare_entry ("Number of particles", "1000", - Patterns::Double (0.), - "Total number of particles to create (not per processor or per element). " - "The number is parsed as a floating point number (so that one can " - "specify, for example, '1e4' particles) but it is interpreted as " - "an integer, of course."); - - prm.declare_entry ("Random cell selection", "true", - Patterns::Bool(), - "If true, particle numbers per cell are calculated randomly " - "according to their respective probability density. " - "This means particle numbers per cell can deviate statistically from " - "the integral of the probability density. If false, " - "first determine how many particles each cell should have " - "based on the integral of the density over each of the cells, " - "and then once we know how many particles we want on each cell, " - "choose their locations randomly within each cell."); - - prm.declare_entry ("Random number seed", "5432", - Patterns::Integer(0), - "The seed for the random number generator that controls " - "the particle generation. Keep constant to generate " - "identical particle distributions in subsequent model " - "runs. Change to get a different distribution. In parallel " - "computations the seed is further modified on each process " - "to ensure different particle patterns on different " - "processes. Note that the number of particles per processor " - "is not affected by the seed."); - } - prm.leave_subsection(); + Functions::ParsedFunction::declare_parameters (prm, 1); + + prm.declare_entry ("Number of particles", "1000", + Patterns::Double (0.), + "Total number of particles to create (not per processor or per element). " + "The number is parsed as a floating point number (so that one can " + "specify, for example, '1e4' particles) but it is interpreted as " + "an integer, of course."); + + prm.declare_entry ("Random cell selection", "true", + Patterns::Bool(), + "If true, particle numbers per cell are calculated randomly " + "according to their respective probability density. " + "This means particle numbers per cell can deviate statistically from " + "the integral of the probability density. If false, " + "first determine how many particles each cell should have " + "based on the integral of the density over each of the cells, " + "and then once we know how many particles we want on each cell, " + "choose their locations randomly within each cell."); + + prm.declare_entry ("Random number seed", "5432", + Patterns::Integer(0), + "The seed for the random number generator that controls " + "the particle generation. Keep constant to generate " + "identical particle distributions in subsequent model " + "runs. Change to get a different distribution. In parallel " + "computations the seed is further modified on each process " + "to ensure different particle patterns on different " + "processes. Note that the number of particles per processor " + "is not affected by the seed."); } prm.leave_subsection(); } @@ -98,30 +94,26 @@ namespace aspect void ProbabilityDensityFunction::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Probability density function"); { - prm.enter_subsection("Probability density function"); - { - n_particles = static_cast(prm.get_double ("Number of particles")); - random_cell_selection = prm.get_bool("Random cell selection"); - random_number_seed = prm.get_integer("Random number seed"); - - try - { - function.parse_parameters (prm); - } - catch (...) - { - std::cerr << "ERROR: FunctionParser failed to parse\n" - << "\t'Particle.Generator.Probability density function'\n" - << "with expression\n" - << "\t'" << prm.get("Function expression") << "'"; - throw; - } - } - prm.leave_subsection(); + n_particles = static_cast(prm.get_double ("Number of particles")); + random_cell_selection = prm.get_bool("Random cell selection"); + random_number_seed = prm.get_integer("Random number seed"); + + try + { + function.parse_parameters (prm); + } + catch (...) + { + std::cerr << "ERROR: FunctionParser failed to parse\n" + << "\t'Particle.Generator.Probability density function'\n" + << "with expression\n" + << "\t'" << prm.get("Function expression") << "'"; + throw; + } } prm.leave_subsection(); } diff --git a/source/particle/generator/random_uniform.cc b/source/particle/generator/random_uniform.cc index 7eed737ae24..3fa2c84efca 100644 --- a/source/particle/generator/random_uniform.cc +++ b/source/particle/generator/random_uniform.cc @@ -47,42 +47,38 @@ namespace aspect void RandomUniform::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Probability density function"); { - prm.enter_subsection("Probability density function"); - { - prm.declare_entry ("Number of particles", "1000", - Patterns::Double (0.), - "Total number of particles to create (not per processor or per element). " - "The number is parsed as a floating point number (so that one can " - "specify, for example, '1e4' particles) but it is interpreted as " - "an integer, of course."); - - prm.declare_entry ("Random cell selection", "true", - Patterns::Bool(), - "If true, particle numbers per cell are calculated randomly " - "according to their respective probability density. " - "This means particle numbers per cell can deviate statistically from " - "the integral of the probability density. If false, " - "first determine how many particles each cell should have " - "based on the integral of the density over each of the cells, " - "and then once we know how many particles we want on each cell, " - "choose their locations randomly within each cell."); - - prm.declare_entry ("Random number seed", "5432", - Patterns::Integer(0), - "The seed for the random number generator that controls " - "the particle generation. Keep constant to generate " - "identical particle distributions in subsequent model " - "runs. Change to get a different distribution. In parallel " - "computations the seed is further modified on each process " - "to ensure different particle patterns on different " - "processes. Note that the number of particles per processor " - "is not affected by the seed."); - } - prm.leave_subsection(); + prm.declare_entry ("Number of particles", "1000", + Patterns::Double (0.), + "Total number of particles to create (not per processor or per element). " + "The number is parsed as a floating point number (so that one can " + "specify, for example, '1e4' particles) but it is interpreted as " + "an integer, of course."); + + prm.declare_entry ("Random cell selection", "true", + Patterns::Bool(), + "If true, particle numbers per cell are calculated randomly " + "according to their respective probability density. " + "This means particle numbers per cell can deviate statistically from " + "the integral of the probability density. If false, " + "first determine how many particles each cell should have " + "based on the integral of the density over each of the cells, " + "and then once we know how many particles we want on each cell, " + "choose their locations randomly within each cell."); + + prm.declare_entry ("Random number seed", "5432", + Patterns::Integer(0), + "The seed for the random number generator that controls " + "the particle generation. Keep constant to generate " + "identical particle distributions in subsequent model " + "runs. Change to get a different distribution. In parallel " + "computations the seed is further modified on each process " + "to ensure different particle patterns on different " + "processes. Note that the number of particles per processor " + "is not affected by the seed."); } prm.leave_subsection(); } @@ -94,17 +90,13 @@ namespace aspect void RandomUniform::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Probability density function"); { - prm.enter_subsection("Probability density function"); - { - n_particles = static_cast(prm.get_double ("Number of particles")); - random_cell_selection = prm.get_bool("Random cell selection"); - random_number_seed = prm.get_integer("Random number seed"); - } - prm.leave_subsection(); + n_particles = static_cast(prm.get_double ("Number of particles")); + random_cell_selection = prm.get_bool("Random cell selection"); + random_number_seed = prm.get_integer("Random number seed"); } prm.leave_subsection(); } diff --git a/source/particle/generator/reference_cell.cc b/source/particle/generator/reference_cell.cc index a56aa459020..cc63692f827 100644 --- a/source/particle/generator/reference_cell.cc +++ b/source/particle/generator/reference_cell.cc @@ -85,22 +85,18 @@ namespace aspect void ReferenceCell::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Reference cell"); { - prm.enter_subsection("Reference cell"); - { - prm.declare_entry ("Number of particles per cell per direction", "2", - Patterns::List(Patterns::Integer(1)), - "List of number of particles to create per cell and spatial dimension. " - "The size of the list is the number of spatial dimensions. If only " - "one value is given, then each spatial dimension is set to the same value. " - "The list of numbers are parsed as a floating point number (so that one can " - "specify, for example, '1e4' particles) but it is interpreted as " - "an integer, of course."); - } - prm.leave_subsection(); + prm.declare_entry ("Number of particles per cell per direction", "2", + Patterns::List(Patterns::Integer(1)), + "List of number of particles to create per cell and spatial dimension. " + "The size of the list is the number of spatial dimensions. If only " + "one value is given, then each spatial dimension is set to the same value. " + "The list of numbers are parsed as a floating point number (so that one can " + "specify, for example, '1e4' particles) but it is interpreted as " + "an integer, of course."); } prm.leave_subsection(); } @@ -112,22 +108,18 @@ namespace aspect void ReferenceCell::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Reference cell"); { - prm.enter_subsection("Reference cell"); - { - const auto n_particles_per_direction = Utilities::possibly_extend_from_1_to_N ( - Utilities::string_to_int( - Utilities::split_string_list(prm.get("Number of particles per cell per direction"))), - dim, - "Number of particles per cell per direction"); - - for (const auto &n_particle_direction: n_particles_per_direction) - number_of_particles.push_back(static_cast (n_particle_direction)); - } - prm.leave_subsection(); + const auto n_particles_per_direction = Utilities::possibly_extend_from_1_to_N ( + Utilities::string_to_int( + Utilities::split_string_list(prm.get("Number of particles per cell per direction"))), + dim, + "Number of particles per cell per direction"); + + for (const auto &n_particle_direction: n_particles_per_direction) + number_of_particles.push_back(static_cast (n_particle_direction)); } prm.leave_subsection(); } diff --git a/source/particle/generator/uniform_box.cc b/source/particle/generator/uniform_box.cc index 6a0099b214e..ca452055b7a 100644 --- a/source/particle/generator/uniform_box.cc +++ b/source/particle/generator/uniform_box.cc @@ -83,39 +83,35 @@ namespace aspect void UniformBox::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Uniform box"); { - prm.enter_subsection("Uniform box"); - { - prm.declare_entry ("Number of particles", "1000", - Patterns::Double (0.), - "Total number of particles to create (not per processor or per element). " - "The number is parsed as a floating point number (so that one can " - "specify, for example, '1e4' particles) but it is interpreted as " - "an integer, of course."); - - prm.declare_entry ("Minimum x", "0.", - Patterns::Double (), - "Minimum x coordinate for the region of particles."); - prm.declare_entry ("Maximum x", "1.", - Patterns::Double (), - "Maximum x coordinate for the region of particles."); - prm.declare_entry ("Minimum y", "0.", - Patterns::Double (), - "Minimum y coordinate for the region of particles."); - prm.declare_entry ("Maximum y", "1.", - Patterns::Double (), - "Maximum y coordinate for the region of particles."); - prm.declare_entry ("Minimum z", "0.", - Patterns::Double (), - "Minimum z coordinate for the region of particles."); - prm.declare_entry ("Maximum z", "1.", - Patterns::Double (), - "Maximum z coordinate for the region of particles."); - } - prm.leave_subsection(); + prm.declare_entry ("Number of particles", "1000", + Patterns::Double (0.), + "Total number of particles to create (not per processor or per element). " + "The number is parsed as a floating point number (so that one can " + "specify, for example, '1e4' particles) but it is interpreted as " + "an integer, of course."); + + prm.declare_entry ("Minimum x", "0.", + Patterns::Double (), + "Minimum x coordinate for the region of particles."); + prm.declare_entry ("Maximum x", "1.", + Patterns::Double (), + "Maximum x coordinate for the region of particles."); + prm.declare_entry ("Minimum y", "0.", + Patterns::Double (), + "Minimum y coordinate for the region of particles."); + prm.declare_entry ("Maximum y", "1.", + Patterns::Double (), + "Maximum y coordinate for the region of particles."); + prm.declare_entry ("Minimum z", "0.", + Patterns::Double (), + "Minimum z coordinate for the region of particles."); + prm.declare_entry ("Maximum z", "1.", + Patterns::Double (), + "Maximum z coordinate for the region of particles."); } prm.leave_subsection(); } @@ -127,31 +123,27 @@ namespace aspect void UniformBox::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Uniform box"); { - prm.enter_subsection("Uniform box"); - { - n_particles = static_cast(prm.get_double ("Number of particles")); - - P_min(0) = prm.get_double ("Minimum x"); - P_max(0) = prm.get_double ("Maximum x"); - P_min(1) = prm.get_double ("Minimum y"); - P_max(1) = prm.get_double ("Maximum y"); - - AssertThrow(P_min(0) < P_max(0), ExcMessage("Minimum x must be less than maximum x")); - AssertThrow(P_min(1) < P_max(1), ExcMessage("Minimum y must be less than maximum y")); - - if (dim == 3) - { - P_min(2) = prm.get_double ("Minimum z"); - P_max(2) = prm.get_double ("Maximum z"); - - AssertThrow(P_min(2) < P_max(2), ExcMessage("Minimum z must be less than maximum z")); - } - } - prm.leave_subsection(); + n_particles = static_cast(prm.get_double ("Number of particles")); + + P_min(0) = prm.get_double ("Minimum x"); + P_max(0) = prm.get_double ("Maximum x"); + P_min(1) = prm.get_double ("Minimum y"); + P_max(1) = prm.get_double ("Maximum y"); + + AssertThrow(P_min(0) < P_max(0), ExcMessage("Minimum x must be less than maximum x")); + AssertThrow(P_min(1) < P_max(1), ExcMessage("Minimum y must be less than maximum y")); + + if (dim == 3) + { + P_min(2) = prm.get_double ("Minimum z"); + P_max(2) = prm.get_double ("Maximum z"); + + AssertThrow(P_min(2) < P_max(2), ExcMessage("Minimum z must be less than maximum z")); + } } prm.leave_subsection(); } diff --git a/source/particle/generator/uniform_radial.cc b/source/particle/generator/uniform_radial.cc index c534cddf11c..5604feb5ecb 100644 --- a/source/particle/generator/uniform_radial.cc +++ b/source/particle/generator/uniform_radial.cc @@ -121,63 +121,59 @@ namespace aspect void UniformRadial::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Uniform radial"); { - prm.enter_subsection("Uniform radial"); - { - prm.declare_entry ("Number of particles", "1000", - Patterns::Double (0.), - "Total number of particles to create (not per processor or per element). " - "The number is parsed as a floating point number (so that one can " - "specify, for example, '1e4' particles) but it is interpreted as " - "an integer, of course."); - - prm.declare_entry ("Center x", "0.", - Patterns::Double (), - "x coordinate for the center of the spherical region, " - "where particles are generated."); - prm.declare_entry ("Center y", "0.", - Patterns::Double (), - "y coordinate for the center of the spherical region, " - "where particles are generated."); - prm.declare_entry ("Center z", "0.", - Patterns::Double (), - "z coordinate for the center of the spherical region, " - "where particles are generated."); - prm.declare_entry ("Minimum radius", "0.", - Patterns::Double (0.), - "Minimum radial coordinate for the region of particles. " - "Measured from the center position."); - prm.declare_entry ("Maximum radius", "1.", - Patterns::Double (), - "Maximum radial coordinate for the region of particles. " - "Measured from the center position."); - prm.declare_entry ("Minimum longitude", "0.", - Patterns::Double (-180., 360.), - "Minimum longitude coordinate for the region of particles " - "in degrees. Measured from the center position."); - prm.declare_entry ("Maximum longitude", "360.", - Patterns::Double (-180., 360.), - "Maximum longitude coordinate for the region of particles " - "in degrees. Measured from the center position."); - prm.declare_entry ("Minimum latitude", "0.", - Patterns::Double (0., 180.), - "Minimum latitude coordinate for the region of particles " - "in degrees. Measured from the center position, and from " - "the north pole."); - prm.declare_entry ("Maximum latitude", "180.", - Patterns::Double (0., 180.), - "Maximum latitude coordinate for the region of particles " - "in degrees. Measured from the center position, and from " - "the north pole."); - prm.declare_entry ("Radial layers", "1", - Patterns::Integer(1), - "The number of radial shells of particles that will be generated " - "around the central point."); - } - prm.leave_subsection(); + prm.declare_entry ("Number of particles", "1000", + Patterns::Double (0.), + "Total number of particles to create (not per processor or per element). " + "The number is parsed as a floating point number (so that one can " + "specify, for example, '1e4' particles) but it is interpreted as " + "an integer, of course."); + + prm.declare_entry ("Center x", "0.", + Patterns::Double (), + "x coordinate for the center of the spherical region, " + "where particles are generated."); + prm.declare_entry ("Center y", "0.", + Patterns::Double (), + "y coordinate for the center of the spherical region, " + "where particles are generated."); + prm.declare_entry ("Center z", "0.", + Patterns::Double (), + "z coordinate for the center of the spherical region, " + "where particles are generated."); + prm.declare_entry ("Minimum radius", "0.", + Patterns::Double (0.), + "Minimum radial coordinate for the region of particles. " + "Measured from the center position."); + prm.declare_entry ("Maximum radius", "1.", + Patterns::Double (), + "Maximum radial coordinate for the region of particles. " + "Measured from the center position."); + prm.declare_entry ("Minimum longitude", "0.", + Patterns::Double (-180., 360.), + "Minimum longitude coordinate for the region of particles " + "in degrees. Measured from the center position."); + prm.declare_entry ("Maximum longitude", "360.", + Patterns::Double (-180., 360.), + "Maximum longitude coordinate for the region of particles " + "in degrees. Measured from the center position."); + prm.declare_entry ("Minimum latitude", "0.", + Patterns::Double (0., 180.), + "Minimum latitude coordinate for the region of particles " + "in degrees. Measured from the center position, and from " + "the north pole."); + prm.declare_entry ("Maximum latitude", "180.", + Patterns::Double (0., 180.), + "Maximum latitude coordinate for the region of particles " + "in degrees. Measured from the center position, and from " + "the north pole."); + prm.declare_entry ("Radial layers", "1", + Patterns::Integer(1), + "The number of radial shells of particles that will be generated " + "around the central point."); } prm.leave_subsection(); } @@ -189,45 +185,41 @@ namespace aspect void UniformRadial::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Generator"); { - prm.enter_subsection("Generator"); + prm.enter_subsection("Uniform radial"); { - prm.enter_subsection("Uniform radial"); - { - n_particles = static_cast(prm.get_double ("Number of particles")); + n_particles = static_cast(prm.get_double ("Number of particles")); - P_center[0] = prm.get_double ("Center x"); - P_center[1] = prm.get_double ("Center y"); + P_center[0] = prm.get_double ("Center x"); + P_center[1] = prm.get_double ("Center y"); - P_min[0] = prm.get_double ("Minimum radius"); - P_max[0] = prm.get_double ("Maximum radius"); - P_min[1] = prm.get_double ("Minimum longitude") * constants::degree_to_radians; - P_max[1] = prm.get_double ("Maximum longitude") * constants::degree_to_radians; + P_min[0] = prm.get_double ("Minimum radius"); + P_max[0] = prm.get_double ("Maximum radius"); + P_min[1] = prm.get_double ("Minimum longitude") * constants::degree_to_radians; + P_max[1] = prm.get_double ("Maximum longitude") * constants::degree_to_radians; - AssertThrow(P_max[1] > P_min[1], - ExcMessage("The maximum longitude you prescribed in the uniform radial" - "particle generator has to be higher than the minimum longitude.")); - AssertThrow(P_max[1] - P_min[1] <= 2.0 * numbers::PI, - ExcMessage("The difference between the maximum and minimum longitude you " - "prescribed in the uniform radial particle generator has to be " - "less than 360 degrees.")); + AssertThrow(P_max[1] > P_min[1], + ExcMessage("The maximum longitude you prescribed in the uniform radial" + "particle generator has to be higher than the minimum longitude.")); + AssertThrow(P_max[1] - P_min[1] <= 2.0 * numbers::PI, + ExcMessage("The difference between the maximum and minimum longitude you " + "prescribed in the uniform radial particle generator has to be " + "less than 360 degrees.")); - if (dim ==3) - { - P_center[2] = prm.get_double ("Center z"); + if (dim ==3) + { + P_center[2] = prm.get_double ("Center z"); - P_min[2] = prm.get_double ("Minimum latitude") * constants::degree_to_radians; - P_max[2] = prm.get_double ("Maximum latitude") * constants::degree_to_radians; + P_min[2] = prm.get_double ("Minimum latitude") * constants::degree_to_radians; + P_max[2] = prm.get_double ("Maximum latitude") * constants::degree_to_radians; - AssertThrow(P_max[2] > P_min[2], - ExcMessage("The maximum latitude you prescribed in the uniform radial" - "particle generator has to be higher than the minimum latitude.")); - } + AssertThrow(P_max[2] > P_min[2], + ExcMessage("The maximum latitude you prescribed in the uniform radial" + "particle generator has to be higher than the minimum latitude.")); + } - radial_layers = prm.get_integer("Radial layers"); - } - prm.leave_subsection(); + radial_layers = prm.get_integer("Radial layers"); } prm.leave_subsection(); } diff --git a/source/particle/integrator/interface.cc b/source/particle/integrator/interface.cc index 7cd137b67fe..88a8342876f 100644 --- a/source/particle/integrator/interface.cc +++ b/source/particle/integrator/interface.cc @@ -101,11 +101,7 @@ namespace aspect create_particle_integrator (ParameterHandler &prm) { std::string name; - prm.enter_subsection ("Particles"); - { - name = prm.get ("Integration scheme"); - } - prm.leave_subsection (); + name = prm.get ("Integration scheme"); return std::get(registered_plugins).create_plugin (name, "Particle::Integrator name"); @@ -118,77 +114,73 @@ namespace aspect declare_parameters (ParameterHandler &prm) { // declare the entry in the parameter file - prm.enter_subsection ("Particles"); - { - const std::string pattern_of_names - = std::get(registered_plugins).get_pattern_of_names (); - - prm.declare_entry ("Integration scheme", "rk2", - Patterns::Selection (pattern_of_names), - "This parameter is used to decide which method to " - "use to solve the equation that describes the position " - "of particles, i.e., $\\frac{d}{dt}\\mathbf x_k(t) = " - "\\mathbf u(\\mathbf x_k(t),t)$, where $k$ is an index " - "that runs over all particles, and $\\mathbf u(\\mathbf x,t)$ " - "is the velocity field that results from the Stokes " - "equations." - "\n\n" - "In practice, the exact velocity $\\mathbf u(\\mathbf x,t)$ " - "is of course not available, but only a numerical " - "approximation $\\mathbf u_h(\\mathbf x,t)$. Furthermore, " - "this approximation is only available at discrete time steps, " - "$\\mathbf u^n(\\mathbf x)=\\mathbf u(\\mathbf x,t^n)$, and " - "these need to be interpolated between time steps if the " - "integrator for the equation above requires an evaluation at " - "time points between the discrete time steps. If we denote this " - "interpolation in time by $\\tilde{\\mathbf u}_h(\\mathbf x,t)$ " - "where $\\tilde{\\mathbf u}_h(\\mathbf x,t^n)=" - "\\mathbf u^n(\\mathbf x)$, then the equation the differential " - "equation solver really tries to solve is " - "$\\frac{d}{dt}\\tilde{\\mathbf x}_k(t) = " - " \\tilde{\\mathbf u}_h(\\mathbf x_k(t),t)$." - "\n\n" - "As a consequence of these considerations, if you try to " - "assess convergence properties of an ODE integrator -- for " - "example to verify that the RK4 integrator converges with " - "fourth order --, it is important to recall that the " - "integrator may not solve the equation you think it " - "solves. If, for example, we call the numerical solution " - "of the ODE $\\tilde{\\mathbf x}_{k,h}(t)$, then the " - "error will typically satisfy a relationship like " - "\\[" - " \\| \\tilde{\\mathbf x}_k(T) - \\tilde{\\mathbf x}_{k,h}(T) \\|" - " \\le" - " C(T) \\Delta t^p" - "\\] " - "where $\\Delta t$ is the time step and $p$ the convergence order " - "of the method, and $C(T)$ is a (generally unknown) constant " - "that depends on the end time $T$ at which one compares the " - "solutions. On the other hand, an analytically computed " - "trajectory would likely use the \\textit{exact} velocity, " - "and one may be tempted to compute " - "$\\| \\mathbf x_k(T) - \\tilde{\\mathbf x}_{k,h}(T) \\|$, " - "but this quantity will, in the best case, only satisfy an " - "estimate of the form " - "\\[" - " \\| \\mathbf x_k(T) - \\tilde{\\mathbf x}_{k,h}(T) \\|" - " \\le" - " C_1(T) \\Delta t^p" - " + C_2(T) \\| \\mathbf u-\\mathbf u_h \\|" - " + C_3(T) \\| \\mathbf u_h-\\tilde{\\mathbf u}_h \\|" - "\\] " - "with appropriately chosen norms for the second and third " - "term. These second and third terms typically converge to " - "zero at relatively low rates (compared to the order $p$ of " - "the integrator, which can often be chosen relatively high) " - "in the mesh size $h$ and the time step size $\\\\Delta t$, " - "limiting the overall accuracy of the ODE integrator." - "\n\n" - "Select one of the following models:\n\n" - + - std::get(registered_plugins).get_description_string()); - } - prm.leave_subsection (); + const std::string pattern_of_names + = std::get(registered_plugins).get_pattern_of_names (); + + prm.declare_entry ("Integration scheme", "rk2", + Patterns::Selection (pattern_of_names), + "This parameter is used to decide which method to " + "use to solve the equation that describes the position " + "of particles, i.e., $\\frac{d}{dt}\\mathbf x_k(t) = " + "\\mathbf u(\\mathbf x_k(t),t)$, where $k$ is an index " + "that runs over all particles, and $\\mathbf u(\\mathbf x,t)$ " + "is the velocity field that results from the Stokes " + "equations." + "\n\n" + "In practice, the exact velocity $\\mathbf u(\\mathbf x,t)$ " + "is of course not available, but only a numerical " + "approximation $\\mathbf u_h(\\mathbf x,t)$. Furthermore, " + "this approximation is only available at discrete time steps, " + "$\\mathbf u^n(\\mathbf x)=\\mathbf u(\\mathbf x,t^n)$, and " + "these need to be interpolated between time steps if the " + "integrator for the equation above requires an evaluation at " + "time points between the discrete time steps. If we denote this " + "interpolation in time by $\\tilde{\\mathbf u}_h(\\mathbf x,t)$ " + "where $\\tilde{\\mathbf u}_h(\\mathbf x,t^n)=" + "\\mathbf u^n(\\mathbf x)$, then the equation the differential " + "equation solver really tries to solve is " + "$\\frac{d}{dt}\\tilde{\\mathbf x}_k(t) = " + " \\tilde{\\mathbf u}_h(\\mathbf x_k(t),t)$." + "\n\n" + "As a consequence of these considerations, if you try to " + "assess convergence properties of an ODE integrator -- for " + "example to verify that the RK4 integrator converges with " + "fourth order --, it is important to recall that the " + "integrator may not solve the equation you think it " + "solves. If, for example, we call the numerical solution " + "of the ODE $\\tilde{\\mathbf x}_{k,h}(t)$, then the " + "error will typically satisfy a relationship like " + "\\[" + " \\| \\tilde{\\mathbf x}_k(T) - \\tilde{\\mathbf x}_{k,h}(T) \\|" + " \\le" + " C(T) \\Delta t^p" + "\\] " + "where $\\Delta t$ is the time step and $p$ the convergence order " + "of the method, and $C(T)$ is a (generally unknown) constant " + "that depends on the end time $T$ at which one compares the " + "solutions. On the other hand, an analytically computed " + "trajectory would likely use the \\textit{exact} velocity, " + "and one may be tempted to compute " + "$\\| \\mathbf x_k(T) - \\tilde{\\mathbf x}_{k,h}(T) \\|$, " + "but this quantity will, in the best case, only satisfy an " + "estimate of the form " + "\\[" + " \\| \\mathbf x_k(T) - \\tilde{\\mathbf x}_{k,h}(T) \\|" + " \\le" + " C_1(T) \\Delta t^p" + " + C_2(T) \\| \\mathbf u-\\mathbf u_h \\|" + " + C_3(T) \\| \\mathbf u_h-\\tilde{\\mathbf u}_h \\|" + "\\] " + "with appropriately chosen norms for the second and third " + "term. These second and third terms typically converge to " + "zero at relatively low rates (compared to the order $p$ of " + "the integrator, which can often be chosen relatively high) " + "in the mesh size $h$ and the time step size $\\\\Delta t$, " + "limiting the overall accuracy of the ODE integrator." + "\n\n" + "Select one of the following models:\n\n" + + + std::get(registered_plugins).get_description_string()); std::get(registered_plugins).declare_parameters (prm); } diff --git a/source/particle/integrator/rk_2.cc b/source/particle/integrator/rk_2.cc index e158c0e8510..adefbe3daf2 100644 --- a/source/particle/integrator/rk_2.cc +++ b/source/particle/integrator/rk_2.cc @@ -188,21 +188,17 @@ namespace aspect void RK2::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Integrator"); { - prm.enter_subsection("Integrator"); + prm.enter_subsection("RK2"); { - prm.enter_subsection("RK2"); - { - prm.declare_entry ("Higher order accurate in time", "true", - Patterns::Bool(), - "Whether to correctly evaluate old and current velocity " - "solution to reach higher-order accuracy in time. If set to " - "'false' only the old velocity solution is evaluated to " - "simulate a first order method in time. This is only " - "recommended for benchmark purposes."); - } - prm.leave_subsection(); + prm.declare_entry ("Higher order accurate in time", "true", + Patterns::Bool(), + "Whether to correctly evaluate old and current velocity " + "solution to reach higher-order accuracy in time. If set to " + "'false' only the old velocity solution is evaluated to " + "simulate a first order method in time. This is only " + "recommended for benchmark purposes."); } prm.leave_subsection(); } @@ -214,15 +210,11 @@ namespace aspect void RK2::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Integrator"); { - prm.enter_subsection("Integrator"); + prm.enter_subsection("RK2"); { - prm.enter_subsection("RK2"); - { - higher_order_in_time = prm.get_bool("Higher order accurate in time"); - } - prm.leave_subsection(); + higher_order_in_time = prm.get_bool("Higher order accurate in time"); } prm.leave_subsection(); } diff --git a/source/particle/interpolator/bilinear_least_squares.cc b/source/particle/interpolator/bilinear_least_squares.cc index a8fc99565a0..ddf245165cb 100644 --- a/source/particle/interpolator/bilinear_least_squares.cc +++ b/source/particle/interpolator/bilinear_least_squares.cc @@ -248,29 +248,25 @@ namespace aspect void BilinearLeastSquares::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Interpolator"); { - prm.enter_subsection("Interpolator"); + prm.enter_subsection("Bilinear least squares"); { - prm.enter_subsection("Bilinear least squares"); - { - prm.declare_entry("Use linear least squares limiter", "false", - Patterns::List(Patterns::Bool()), - "Limit the interpolation of particle properties onto the cell, so that " - "the value of each property is no smaller than its minimum and no " - "larger than its maximum on the particles of each cell, and the " - "average of neighboring cells. If more than one value is given, " - "it will be treated as a list with one component per particle property."); - prm.declare_entry("Use boundary extrapolation", "false", - Patterns::List(Patterns::Bool()), - "Extends the range used by 'Use linear least squares limiter' " - "by linearly interpolating values at cell boundaries from neighboring " - "cells. If more than one value is given, it will be treated as a list " - "with one component per particle property. Enabling 'Use boundary " - "extrapolation' requires enabling 'Use linear least squares " - "limiter'."); - } - prm.leave_subsection(); + prm.declare_entry("Use linear least squares limiter", "false", + Patterns::List(Patterns::Bool()), + "Limit the interpolation of particle properties onto the cell, so that " + "the value of each property is no smaller than its minimum and no " + "larger than its maximum on the particles of each cell, and the " + "average of neighboring cells. If more than one value is given, " + "it will be treated as a list with one component per particle property."); + prm.declare_entry("Use boundary extrapolation", "false", + Patterns::List(Patterns::Bool()), + "Extends the range used by 'Use linear least squares limiter' " + "by linearly interpolating values at cell boundaries from neighboring " + "cells. If more than one value is given, it will be treated as a list " + "with one component per particle property. Enabling 'Use boundary " + "extrapolation' requires enabling 'Use linear least squares " + "limiter'."); } prm.leave_subsection(); } @@ -283,72 +279,67 @@ namespace aspect BilinearLeastSquares::parse_parameters (ParameterHandler &prm) { fallback_interpolator.parse_parameters(prm); - prm.enter_subsection("Particles"); + prm.enter_subsection("Interpolator"); { - prm.enter_subsection("Interpolator"); + prm.enter_subsection("Bilinear least squares"); { - prm.enter_subsection("Bilinear least squares"); - { - const Postprocess::Particles &particle_postprocessor = - this->get_postprocess_manager().template get_matching_postprocessor>(); - const auto &particle_property_information = particle_postprocessor.get_particle_world().get_property_manager().get_data_info(); - const unsigned int n_property_components = particle_property_information.n_components(); - const unsigned int n_internal_components = particle_property_information.get_components_by_field_name("internal: integrator properties"); - - std::vector linear_least_squares_limiter_split = Utilities::split_string_list(prm.get("Use linear least squares limiter")); - std::vector linear_least_squares_limiter_parsed; - if (linear_least_squares_limiter_split.size() == 1) - { - linear_least_squares_limiter_parsed = std::vector(n_property_components - n_internal_components, Utilities::string_to_bool(linear_least_squares_limiter_split[0])); - } - else if (linear_least_squares_limiter_split.size() == n_property_components - n_internal_components) - { - for (const auto &component: linear_least_squares_limiter_split) - linear_least_squares_limiter_parsed.push_back(Utilities::string_to_bool(component)); - } - else - { - AssertThrow(false, ExcMessage("The size of 'Use linear least squares limiter' should either be 1 or the number of particle properties")); - } - for (unsigned int i = 0; i < n_internal_components; ++i) - linear_least_squares_limiter_parsed.push_back(false); - use_linear_least_squares_limiter = ComponentMask(linear_least_squares_limiter_parsed); - - - - const std::vector boundary_extrapolation_split = Utilities::split_string_list(prm.get("Use boundary extrapolation")); - std::vector boundary_extrapolation_parsed; - if (boundary_extrapolation_split.size() == 1) - { - boundary_extrapolation_parsed = std::vector(n_property_components - n_internal_components, Utilities::string_to_bool(boundary_extrapolation_split[0])); - } - else if (boundary_extrapolation_split.size() == n_property_components - n_internal_components) - { - for (const auto &component: boundary_extrapolation_split) - boundary_extrapolation_parsed.push_back(Utilities::string_to_bool(component)); - } - else - { - AssertThrow(false, ExcMessage("The size of 'Use boundary extrapolation' should either be 1 or the number of particle properties")); - } - for (unsigned int i = 0; i < n_internal_components; ++i) - boundary_extrapolation_parsed.push_back(false); - use_boundary_extrapolation = ComponentMask(boundary_extrapolation_parsed); - for (unsigned int property_index = 0; property_index < n_property_components - n_internal_components; ++property_index) - { - AssertThrow(use_linear_least_squares_limiter[property_index] || !use_boundary_extrapolation[property_index], - ExcMessage("'Use boundary extrapolation' must be set with 'Use linear least squares limiter' to be valid.")); - } - } - prm.leave_subsection(); + const Postprocess::Particles &particle_postprocessor = + this->get_postprocess_manager().template get_matching_postprocessor>(); + const auto &particle_property_information = particle_postprocessor.get_particle_world().get_property_manager().get_data_info(); + const unsigned int n_property_components = particle_property_information.n_components(); + const unsigned int n_internal_components = particle_property_information.get_components_by_field_name("internal: integrator properties"); + + std::vector linear_least_squares_limiter_split = Utilities::split_string_list(prm.get("Use linear least squares limiter")); + std::vector linear_least_squares_limiter_parsed; + if (linear_least_squares_limiter_split.size() == 1) + { + linear_least_squares_limiter_parsed = std::vector(n_property_components - n_internal_components, Utilities::string_to_bool(linear_least_squares_limiter_split[0])); + } + else if (linear_least_squares_limiter_split.size() == n_property_components - n_internal_components) + { + for (const auto &component: linear_least_squares_limiter_split) + linear_least_squares_limiter_parsed.push_back(Utilities::string_to_bool(component)); + } + else + { + AssertThrow(false, ExcMessage("The size of 'Use linear least squares limiter' should either be 1 or the number of particle properties")); + } + for (unsigned int i = 0; i < n_internal_components; ++i) + linear_least_squares_limiter_parsed.push_back(false); + use_linear_least_squares_limiter = ComponentMask(linear_least_squares_limiter_parsed); + + + + const std::vector boundary_extrapolation_split = Utilities::split_string_list(prm.get("Use boundary extrapolation")); + std::vector boundary_extrapolation_parsed; + if (boundary_extrapolation_split.size() == 1) + { + boundary_extrapolation_parsed = std::vector(n_property_components - n_internal_components, Utilities::string_to_bool(boundary_extrapolation_split[0])); + } + else if (boundary_extrapolation_split.size() == n_property_components - n_internal_components) + { + for (const auto &component: boundary_extrapolation_split) + boundary_extrapolation_parsed.push_back(Utilities::string_to_bool(component)); + } + else + { + AssertThrow(false, ExcMessage("The size of 'Use boundary extrapolation' should either be 1 or the number of particle properties")); + } + for (unsigned int i = 0; i < n_internal_components; ++i) + boundary_extrapolation_parsed.push_back(false); + use_boundary_extrapolation = ComponentMask(boundary_extrapolation_parsed); + for (unsigned int property_index = 0; property_index < n_property_components - n_internal_components; ++property_index) + { + AssertThrow(use_linear_least_squares_limiter[property_index] || !use_boundary_extrapolation[property_index], + ExcMessage("'Use boundary extrapolation' must be set with 'Use linear least squares limiter' to be valid.")); + } } prm.leave_subsection(); - - const bool limiter_enabled_for_at_least_one_property = (use_linear_least_squares_limiter.n_selected_components() != 0); - AssertThrow(limiter_enabled_for_at_least_one_property == false || prm.get_bool("Update ghost particles") == true, - ExcMessage("If 'Use linear least squares limiter' is enabled for any particle property, then 'Update ghost particles' must be set to true")); } prm.leave_subsection(); + const bool limiter_enabled_for_at_least_one_property = (use_linear_least_squares_limiter.n_selected_components() != 0); + AssertThrow(limiter_enabled_for_at_least_one_property == false || prm.get_bool("Update ghost particles") == true, + ExcMessage("If 'Use linear least squares limiter' is enabled for any particle property, then 'Update ghost particles' must be set to true")); } } } diff --git a/source/particle/interpolator/cell_average.cc b/source/particle/interpolator/cell_average.cc index bb627ab2405..9401b39f6ec 100644 --- a/source/particle/interpolator/cell_average.cc +++ b/source/particle/interpolator/cell_average.cc @@ -123,16 +123,12 @@ namespace aspect void CellAverage::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); - { - prm.declare_entry ("Allow cells without particles", "false", - Patterns::Bool (), - "By default, every cell needs to contain particles to use this interpolator " - "plugin. If this parameter is set to true, cells are allowed to have no particles, " - "In case both the current cell and its neighbors are empty, " - "the interpolator will return 0 for the current cell's properties."); - } - prm.leave_subsection (); + prm.declare_entry ("Allow cells without particles", "false", + Patterns::Bool (), + "By default, every cell needs to contain particles to use this interpolator " + "plugin. If this parameter is set to true, cells are allowed to have no particles, " + "In case both the current cell and its neighbors are empty, " + "the interpolator will return 0 for the current cell's properties."); } @@ -141,11 +137,7 @@ namespace aspect void CellAverage::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); - { - allow_cells_without_particles = prm.get_bool("Allow cells without particles"); - } - prm.leave_subsection (); + allow_cells_without_particles = prm.get_bool("Allow cells without particles"); } } } diff --git a/source/particle/interpolator/harmonic_average.cc b/source/particle/interpolator/harmonic_average.cc index 1f8c6fec750..6629fba913b 100644 --- a/source/particle/interpolator/harmonic_average.cc +++ b/source/particle/interpolator/harmonic_average.cc @@ -131,16 +131,12 @@ namespace aspect void HarmonicAverage::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); - { - prm.declare_entry ("Allow cells without particles", "false", - Patterns::Bool (), - "By default, every cell needs to contain particles to use this interpolator " - "plugin. If this parameter is set to true, cells are allowed to have no particles. " - "In case both the current cell and its neighbors are empty, " - "the interpolator will return 0 for the current cell's properties."); - } - prm.leave_subsection (); + prm.declare_entry ("Allow cells without particles", "false", + Patterns::Bool (), + "By default, every cell needs to contain particles to use this interpolator " + "plugin. If this parameter is set to true, cells are allowed to have no particles. " + "In case both the current cell and its neighbors are empty, " + "the interpolator will return 0 for the current cell's properties."); } @@ -149,11 +145,7 @@ namespace aspect void HarmonicAverage::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); - { - allow_cells_without_particles = prm.get_bool("Allow cells without particles"); - } - prm.leave_subsection (); + allow_cells_without_particles = prm.get_bool("Allow cells without particles"); } } } diff --git a/source/particle/interpolator/interface.cc b/source/particle/interpolator/interface.cc index 39289849027..83a50104dec 100644 --- a/source/particle/interpolator/interface.cc +++ b/source/particle/interpolator/interface.cc @@ -61,11 +61,7 @@ namespace aspect create_particle_interpolator (ParameterHandler &prm) { std::string name; - prm.enter_subsection ("Particles"); - { - name = prm.get ("Interpolation scheme"); - } - prm.leave_subsection (); + name = prm.get ("Interpolation scheme"); return std::get(registered_plugins).create_plugin (name, "Particle::Interpolator name"); @@ -78,18 +74,14 @@ namespace aspect declare_parameters (ParameterHandler &prm) { // declare the entry in the parameter file - prm.enter_subsection ("Particles"); - { - const std::string pattern_of_names - = std::get(registered_plugins).get_pattern_of_names (); - - prm.declare_entry ("Interpolation scheme", "cell average", - Patterns::Selection (pattern_of_names), - "Select one of the following models:\n\n" - + - std::get(registered_plugins).get_description_string()); - } - prm.leave_subsection (); + const std::string pattern_of_names + = std::get(registered_plugins).get_pattern_of_names (); + + prm.declare_entry ("Interpolation scheme", "cell average", + Patterns::Selection (pattern_of_names), + "Select one of the following models:\n\n" + + + std::get(registered_plugins).get_description_string()); std::get(registered_plugins).declare_parameters (prm); } diff --git a/source/particle/interpolator/nearest_neighbor.cc b/source/particle/interpolator/nearest_neighbor.cc index 76ecf359a81..2d069370d56 100644 --- a/source/particle/interpolator/nearest_neighbor.cc +++ b/source/particle/interpolator/nearest_neighbor.cc @@ -122,16 +122,12 @@ namespace aspect void NearestNeighbor::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); - { - prm.declare_entry ("Allow cells without particles", "false", - Patterns::Bool (), - "By default, every cell needs to contain particles to use this interpolator " - "plugin. If this parameter is set to true, cells are allowed to have no particles. " - "In case both the current cell and its neighbors are empty, " - "the interpolator will return 0 for the current cell's properties."); - } - prm.leave_subsection (); + prm.declare_entry ("Allow cells without particles", "false", + Patterns::Bool (), + "By default, every cell needs to contain particles to use this interpolator " + "plugin. If this parameter is set to true, cells are allowed to have no particles. " + "In case both the current cell and its neighbors are empty, " + "the interpolator will return 0 for the current cell's properties."); } @@ -140,11 +136,7 @@ namespace aspect void NearestNeighbor::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); - { - allow_cells_without_particles = prm.get_bool("Allow cells without particles"); - } - prm.leave_subsection (); + allow_cells_without_particles = prm.get_bool("Allow cells without particles"); } } } diff --git a/source/particle/interpolator/quadratic_least_squares.cc b/source/particle/interpolator/quadratic_least_squares.cc index 95b110d10b5..3311ec1c984 100644 --- a/source/particle/interpolator/quadratic_least_squares.cc +++ b/source/particle/interpolator/quadratic_least_squares.cc @@ -527,29 +527,25 @@ namespace aspect void QuadraticLeastSquares::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Interpolator"); { - prm.enter_subsection("Interpolator"); + prm.enter_subsection("Quadratic least squares"); { - prm.enter_subsection("Quadratic least squares"); - { - prm.declare_entry("Use quadratic least squares limiter", "true", - Patterns::List(Patterns::Bool()), - "Limit the interpolation of particle properties onto the cell, so that " - "the value of each property is no smaller than its minimum and no " - "larger than its maximum on the particles of each cell, and the " - "average of neighboring cells. If more than one value is given, " - "it will be treated as a list with one component per particle property."); - prm.declare_entry("Use boundary extrapolation", "false", - Patterns::List(Patterns::Bool()), - "Extends the range used by 'Use quadratic least squares limiter' " - "by linearly interpolating values at cell boundaries from neighboring " - "cells. If more than one value is given, it will be treated as a list " - "with one component per particle property. Enabling 'Use boundary " - "extrapolation' requires enabling 'Use quadratic least squares " - "limiter'."); - } - prm.leave_subsection(); + prm.declare_entry("Use quadratic least squares limiter", "true", + Patterns::List(Patterns::Bool()), + "Limit the interpolation of particle properties onto the cell, so that " + "the value of each property is no smaller than its minimum and no " + "larger than its maximum on the particles of each cell, and the " + "average of neighboring cells. If more than one value is given, " + "it will be treated as a list with one component per particle property."); + prm.declare_entry("Use boundary extrapolation", "false", + Patterns::List(Patterns::Bool()), + "Extends the range used by 'Use quadratic least squares limiter' " + "by linearly interpolating values at cell boundaries from neighboring " + "cells. If more than one value is given, it will be treated as a list " + "with one component per particle property. Enabling 'Use boundary " + "extrapolation' requires enabling 'Use quadratic least squares " + "limiter'."); } prm.leave_subsection(); } @@ -561,74 +557,72 @@ namespace aspect QuadraticLeastSquares::parse_parameters (ParameterHandler &prm) { fallback_interpolator.parse_parameters(prm); - prm.enter_subsection("Particles"); + + prm.enter_subsection("Interpolator"); { - prm.enter_subsection("Interpolator"); + prm.enter_subsection("Quadratic least squares"); { - prm.enter_subsection("Quadratic least squares"); - { - const Postprocess::Particles &particle_postprocessor = - this->get_postprocess_manager().template get_matching_postprocessor>(); - const auto &particle_property_information = particle_postprocessor.get_particle_world().get_property_manager().get_data_info(); - const unsigned int n_property_components = particle_property_information.n_components(); - const unsigned int n_internal_components = particle_property_information.get_components_by_field_name("internal: integrator properties"); - - const std::vector quadratic_least_squares_limiter_split = Utilities::split_string_list(prm.get("Use quadratic least squares limiter")); - std::vector quadratic_least_squares_limiter_parsed; - if (quadratic_least_squares_limiter_split.size() == 1) - { - quadratic_least_squares_limiter_parsed = std::vector(n_property_components - n_internal_components, Utilities::string_to_bool(quadratic_least_squares_limiter_split[0])); - } - else if (quadratic_least_squares_limiter_split.size() == n_property_components - n_internal_components) - { - for (const auto &component: quadratic_least_squares_limiter_split) - quadratic_least_squares_limiter_parsed.push_back(Utilities::string_to_bool(component)); - } - else - { - AssertThrow(false, ExcMessage("The size of 'Use quadratic least squares limiter' should either be 1 or the number of particle properties")); - } - for (unsigned int i = 0; i < n_internal_components; ++i) - quadratic_least_squares_limiter_parsed.push_back(false); - use_quadratic_least_squares_limiter = ComponentMask(quadratic_least_squares_limiter_parsed); + const Postprocess::Particles &particle_postprocessor = + this->get_postprocess_manager().template get_matching_postprocessor>(); + const auto &particle_property_information = particle_postprocessor.get_particle_world().get_property_manager().get_data_info(); + const unsigned int n_property_components = particle_property_information.n_components(); + const unsigned int n_internal_components = particle_property_information.get_components_by_field_name("internal: integrator properties"); + + const std::vector quadratic_least_squares_limiter_split = Utilities::split_string_list(prm.get("Use quadratic least squares limiter")); + std::vector quadratic_least_squares_limiter_parsed; + if (quadratic_least_squares_limiter_split.size() == 1) + { + quadratic_least_squares_limiter_parsed = std::vector(n_property_components - n_internal_components, Utilities::string_to_bool(quadratic_least_squares_limiter_split[0])); + } + else if (quadratic_least_squares_limiter_split.size() == n_property_components - n_internal_components) + { + for (const auto &component: quadratic_least_squares_limiter_split) + quadratic_least_squares_limiter_parsed.push_back(Utilities::string_to_bool(component)); + } + else + { + AssertThrow(false, ExcMessage("The size of 'Use quadratic least squares limiter' should either be 1 or the number of particle properties")); + } + for (unsigned int i = 0; i < n_internal_components; ++i) + quadratic_least_squares_limiter_parsed.push_back(false); + use_quadratic_least_squares_limiter = ComponentMask(quadratic_least_squares_limiter_parsed); - const std::vector boundary_extrapolation_split = Utilities::split_string_list(prm.get("Use boundary extrapolation")); - std::vector boundary_extrapolation_parsed; - if (boundary_extrapolation_split.size() == 1) - { - boundary_extrapolation_parsed = std::vector(n_property_components - n_internal_components, Utilities::string_to_bool(boundary_extrapolation_split[0])); - } - else if (boundary_extrapolation_split.size() == n_property_components - n_internal_components) - { - for (const auto &component: boundary_extrapolation_split) - boundary_extrapolation_parsed.push_back(Utilities::string_to_bool(component)); - } - else - { - AssertThrow(false, ExcMessage("The size of 'Use boundary extrapolation' should either be 1 or the number of particle properties")); - } - for (unsigned int i = 0; i < n_internal_components; ++i) - boundary_extrapolation_parsed.push_back(false); - use_boundary_extrapolation = ComponentMask(boundary_extrapolation_parsed); - for (unsigned int property_index = 0; property_index < n_property_components - n_internal_components; ++property_index) - { - AssertThrow(use_quadratic_least_squares_limiter[property_index] || !use_boundary_extrapolation[property_index], - ExcMessage("'Use boundary extrapolation' must be set with 'Use quadratic least squares limiter' to be valid.")); - } + const std::vector boundary_extrapolation_split = Utilities::split_string_list(prm.get("Use boundary extrapolation")); + std::vector boundary_extrapolation_parsed; + if (boundary_extrapolation_split.size() == 1) + { + boundary_extrapolation_parsed = std::vector(n_property_components - n_internal_components, Utilities::string_to_bool(boundary_extrapolation_split[0])); + } + else if (boundary_extrapolation_split.size() == n_property_components - n_internal_components) + { + for (const auto &component: boundary_extrapolation_split) + boundary_extrapolation_parsed.push_back(Utilities::string_to_bool(component)); + } + else + { + AssertThrow(false, ExcMessage("The size of 'Use boundary extrapolation' should either be 1 or the number of particle properties")); + } + for (unsigned int i = 0; i < n_internal_components; ++i) + boundary_extrapolation_parsed.push_back(false); + use_boundary_extrapolation = ComponentMask(boundary_extrapolation_parsed); + for (unsigned int property_index = 0; property_index < n_property_components - n_internal_components; ++property_index) + { + AssertThrow(use_quadratic_least_squares_limiter[property_index] || !use_boundary_extrapolation[property_index], + ExcMessage("'Use boundary extrapolation' must be set with 'Use quadratic least squares limiter' to be valid.")); + } - } - prm.leave_subsection(); } prm.leave_subsection(); - - // In general n_selected_components() requests an argument of the ComponentMask's size since it could be initialized to be entirely true without a size. - // Here it is given a size equal to n_property_components, so that argument is not necessary. - const bool limiter_enabled_for_at_least_one_property = (use_quadratic_least_squares_limiter.n_selected_components() != 0); - AssertThrow(limiter_enabled_for_at_least_one_property == false || prm.get_bool("Update ghost particles") == true, - ExcMessage("If 'Use quadratic least squares limiter' is enabled for any particle property, then 'Update ghost particles' must be set to true")); } prm.leave_subsection(); + + // In general n_selected_components() requests an argument of the ComponentMask's size since it could be initialized to be entirely true without a size. + // Here it is given a size equal to n_property_components, so that argument is not necessary. + const bool limiter_enabled_for_at_least_one_property = (use_quadratic_least_squares_limiter.n_selected_components() != 0); + AssertThrow(limiter_enabled_for_at_least_one_property == false || prm.get_bool("Update ghost particles") == true, + ExcMessage("If 'Use quadratic least squares limiter' is enabled for any particle property, then 'Update ghost particles' must be set to true")); + } } } diff --git a/source/particle/property/cpo_bingham_average.cc b/source/particle/property/cpo_bingham_average.cc index e05673abdfa..3e85ce069b9 100644 --- a/source/particle/property/cpo_bingham_average.cc +++ b/source/particle/property/cpo_bingham_average.cc @@ -224,24 +224,20 @@ namespace aspect void CpoBinghamAverage::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("CPO Bingham Average"); { - prm.enter_subsection("CPO Bingham Average"); - { - prm.declare_entry ("Random number seed", "1", - Patterns::Integer (0), - "The seed used to generate random numbers. This will make sure that " - "results are reproducible as long as the problem is run with the " - "same amount of MPI processes. It is implemented as final seed = " - "Random number seed + MPI Rank. "); - - prm.declare_entry ("Number of samples", "0", - Patterns::Double(0), - "This determines how many samples are taken when using the random " - "draw volume averaging. Setting it to zero means that the number of " - "samples is set to be equal to the number of grains."); - } - prm.leave_subsection (); + prm.declare_entry ("Random number seed", "1", + Patterns::Integer (0), + "The seed used to generate random numbers. This will make sure that " + "results are reproducible as long as the problem is run with the " + "same amount of MPI processes. It is implemented as final seed = " + "Random number seed + MPI Rank. "); + + prm.declare_entry ("Number of samples", "0", + Patterns::Double(0), + "This determines how many samples are taken when using the random " + "draw volume averaging. Setting it to zero means that the number of " + "samples is set to be equal to the number of grains."); } prm.leave_subsection (); } @@ -252,23 +248,18 @@ namespace aspect void CpoBinghamAverage::parse_parameters (ParameterHandler &prm) { - - prm.enter_subsection("Particles"); + prm.enter_subsection("CPO Bingham Average"); { - prm.enter_subsection("CPO Bingham Average"); - { - // Get a pointer to the CPO particle property. - cpo_particle_property = std::make_unique> ( - this->get_particle_world().get_property_manager().template get_matching_property>()); - - random_number_seed = prm.get_integer ("Random number seed"); - n_grains = cpo_particle_property->get_number_of_grains(); - n_minerals = cpo_particle_property->get_number_of_minerals(); - n_samples = prm.get_integer("Number of samples"); - if (n_samples == 0) - n_samples = n_grains; - } - prm.leave_subsection (); + // Get a pointer to the CPO particle property. + cpo_particle_property = std::make_unique> ( + this->get_particle_world().get_property_manager().template get_matching_property>()); + + random_number_seed = prm.get_integer ("Random number seed"); + n_grains = cpo_particle_property->get_number_of_grains(); + n_minerals = cpo_particle_property->get_number_of_minerals(); + n_samples = prm.get_integer("Number of samples"); + if (n_samples == 0) + n_samples = n_grains; } prm.leave_subsection (); } diff --git a/source/particle/property/cpo_elastic_tensor.cc b/source/particle/property/cpo_elastic_tensor.cc index e6f2777da0b..ddc2080fc14 100644 --- a/source/particle/property/cpo_elastic_tensor.cc +++ b/source/particle/property/cpo_elastic_tensor.cc @@ -228,20 +228,16 @@ namespace aspect void CpoElasticTensor::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Crystal Preferred Orientation"); { - prm.enter_subsection("Crystal Preferred Orientation"); + n_grains = prm.get_integer("Number of grains per particle"); + prm.enter_subsection("Initial grains"); { - n_grains = prm.get_integer("Number of grains per particle"); - prm.enter_subsection("Initial grains"); - { - n_minerals = dealii::Utilities::split_string_list(prm.get("Minerals")).size(); - } - prm.leave_subsection(); + n_minerals = dealii::Utilities::split_string_list(prm.get("Minerals")).size(); } prm.leave_subsection(); } - prm.leave_subsection (); + prm.leave_subsection(); } } } diff --git a/source/particle/property/crystal_preferred_orientation.cc b/source/particle/property/crystal_preferred_orientation.cc index 91b61183554..3f849f0ca4d 100644 --- a/source/particle/property/crystal_preferred_orientation.cc +++ b/source/particle/property/crystal_preferred_orientation.cc @@ -1015,102 +1015,98 @@ namespace aspect void CrystalPreferredOrientation::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Crystal Preferred Orientation"); { - prm.enter_subsection("Crystal Preferred Orientation"); + prm.declare_entry ("Random number seed", "1", + Patterns::Integer (0), + "The seed used to generate random numbers. This will make sure that " + "results are reproducible as long as the problem is run with the " + "same number of MPI processes. It is implemented as final seed = " + "user seed + MPI Rank. "); + + prm.declare_entry ("Number of grains per particle", "50", + Patterns::Integer (1), + "The number of grains of each different mineral " + "each particle contains."); + + prm.declare_entry ("Property advection method", "Backward Euler", + Patterns::Anything(), + "Options: Forward Euler, Backward Euler"); + + prm.declare_entry ("Property advection tolerance", "1e-10", + Patterns::Double(0), + "The Backward Euler property advection method involve internal iterations. " + "This option allows for setting a tolerance. When the norm of tensor new - tensor old is " + "smaller than this tolerance, the iteration is stopped."); + + prm.declare_entry ("Property advection max iterations", "100", + Patterns::Integer(0), + "The Backward Euler property advection method involve internal iterations. " + "This option allows for setting the maximum number of iterations. Note that when the iteration " + "is ended by the max iteration amount an assert is thrown."); + + prm.declare_entry ("CPO derivatives algorithm", "Spin tensor", + Patterns::List(Patterns::Anything()), + "Options: Spin tensor"); + + prm.enter_subsection("Initial grains"); { - prm.declare_entry ("Random number seed", "1", - Patterns::Integer (0), - "The seed used to generate random numbers. This will make sure that " - "results are reproducible as long as the problem is run with the " - "same number of MPI processes. It is implemented as final seed = " - "user seed + MPI Rank. "); - - prm.declare_entry ("Number of grains per particle", "50", - Patterns::Integer (1), - "The number of grains of each different mineral " - "each particle contains."); - - prm.declare_entry ("Property advection method", "Backward Euler", - Patterns::Anything(), - "Options: Forward Euler, Backward Euler"); - - prm.declare_entry ("Property advection tolerance", "1e-10", + prm.declare_entry("Model name","Uniform grains and random uniform rotations", + Patterns::Anything(), + "The model used to initialize the CPO for all particles. " + "Currently 'Uniform grains and random uniform rotations' and 'World Builder' are the only valid option."); + + prm.declare_entry ("Minerals", "Olivine: Karato 2008, Enstatite", + Patterns::List(Patterns::Anything()), + "This determines what minerals and fabrics or fabric selectors are used used for the LPO/CPO calculation. " + "The options are Olivine: Passive, A-fabric, Olivine: B-fabric, Olivine: C-fabric, Olivine: D-fabric, " + "Olivine: E-fabric, Olivine: Karato 2008 or Enstatite. Passive sets all RRSS entries to the maximum. The " + "Karato 2008 selector selects a fabric based on stress and water content as defined in " + "figure 4 of the Karato 2008 review paper (doi: 10.1146/annurev.earth.36.031207.124120)."); + + + prm.declare_entry ("Volume fractions minerals", "0.7, 0.3", + Patterns::List(Patterns::Double(0)), + "The volume fractions for the different minerals. " + "There need to be the same number of values as there are minerals." + "Note that the currently implemented scheme is incompressible and " + "does not allow chemical interaction or the formation of new phases"); + } + prm.leave_subsection (); + + prm.enter_subsection("D-Rex 2004"); + { + + prm.declare_entry ("Mobility", "50", Patterns::Double(0), - "The Backward Euler property advection method involve internal iterations. " - "This option allows for setting a tolerance. When the norm of tensor new - tensor old is " - "smaller than this tolerance, the iteration is stopped."); + "The dimensionless intrinsic grain boundary mobility for both olivine and enstatite."); - prm.declare_entry ("Property advection max iterations", "100", - Patterns::Integer(0), - "The Backward Euler property advection method involve internal iterations. " - "This option allows for setting the maximum number of iterations. Note that when the iteration " - "is ended by the max iteration amount an assert is thrown."); + prm.declare_entry ("Volume fractions minerals", "0.5, 0.5", + Patterns::List(Patterns::Double(0)), + "The volume fraction for the different minerals. " + "There need to be the same amount of values as there are minerals"); - prm.declare_entry ("CPO derivatives algorithm", "Spin tensor", - Patterns::List(Patterns::Anything()), - "Options: Spin tensor"); + prm.declare_entry ("Stress exponents", "3.5", + Patterns::Double(0), + "This is the power law exponent that characterizes the rheology of the " + "slip systems. It is used in equation 11 of Kaminski et al., 2004."); - prm.enter_subsection("Initial grains"); - { - prm.declare_entry("Model name","Uniform grains and random uniform rotations", - Patterns::Anything(), - "The model used to initialize the CPO for all particles. " - "Currently 'Uniform grains and random uniform rotations' and 'World Builder' are the only valid option."); - - prm.declare_entry ("Minerals", "Olivine: Karato 2008, Enstatite", - Patterns::List(Patterns::Anything()), - "This determines what minerals and fabrics or fabric selectors are used used for the LPO/CPO calculation. " - "The options are Olivine: Passive, A-fabric, Olivine: B-fabric, Olivine: C-fabric, Olivine: D-fabric, " - "Olivine: E-fabric, Olivine: Karato 2008 or Enstatite. Passive sets all RRSS entries to the maximum. The " - "Karato 2008 selector selects a fabric based on stress and water content as defined in " - "figure 4 of the Karato 2008 review paper (doi: 10.1146/annurev.earth.36.031207.124120)."); - - - prm.declare_entry ("Volume fractions minerals", "0.7, 0.3", - Patterns::List(Patterns::Double(0)), - "The volume fractions for the different minerals. " - "There need to be the same number of values as there are minerals." - "Note that the currently implemented scheme is incompressible and " - "does not allow chemical interaction or the formation of new phases"); - } - prm.leave_subsection (); + prm.declare_entry ("Exponents p", "1.5", + Patterns::Double(0), + "This is exponent p as defined in equation 11 of Kaminski et al., 2004. "); - prm.enter_subsection("D-Rex 2004"); - { + prm.declare_entry ("Nucleation efficiency", "5", + Patterns::Double(0), + "This is the dimensionless nucleation rate as defined in equation 8 of " + "Kaminski et al., 2004. "); - prm.declare_entry ("Mobility", "50", - Patterns::Double(0), - "The dimensionless intrinsic grain boundary mobility for both olivine and enstatite."); - - prm.declare_entry ("Volume fractions minerals", "0.5, 0.5", - Patterns::List(Patterns::Double(0)), - "The volume fraction for the different minerals. " - "There need to be the same amount of values as there are minerals"); - - prm.declare_entry ("Stress exponents", "3.5", - Patterns::Double(0), - "This is the power law exponent that characterizes the rheology of the " - "slip systems. It is used in equation 11 of Kaminski et al., 2004."); - - prm.declare_entry ("Exponents p", "1.5", - Patterns::Double(0), - "This is exponent p as defined in equation 11 of Kaminski et al., 2004. "); - - prm.declare_entry ("Nucleation efficiency", "5", - Patterns::Double(0), - "This is the dimensionless nucleation rate as defined in equation 8 of " - "Kaminski et al., 2004. "); - - prm.declare_entry ("Threshold GBS", "0.3", - Patterns::Double(0), - "The Dimensionless Grain Boundary Sliding (GBS) threshold. " - "This is a grain size threshold below which grain deform by GBS and " - "become strain-free grains."); - } - prm.leave_subsection(); + prm.declare_entry ("Threshold GBS", "0.3", + Patterns::Double(0), + "The Dimensionless Grain Boundary Sliding (GBS) threshold. " + "This is a grain size threshold below which grain deform by GBS and " + "become strain-free grains."); } - prm.leave_subsection (); + prm.leave_subsection(); } prm.leave_subsection (); } @@ -1125,137 +1121,133 @@ namespace aspect "2d computations will work when this assert is removed, but you will need to make sure that the " "correct 3d strain-rate and velocity gradient tensors are provided to the algorithm.")); - prm.enter_subsection("Particles"); + prm.enter_subsection("Crystal Preferred Orientation"); { - prm.enter_subsection("Crystal Preferred Orientation"); - { - random_number_seed = prm.get_integer ("Random number seed"); - n_grains = prm.get_integer("Number of grains per particle"); + random_number_seed = prm.get_integer ("Random number seed"); + n_grains = prm.get_integer("Number of grains per particle"); - property_advection_tolerance = prm.get_double("Property advection tolerance"); - property_advection_max_iterations = prm.get_integer ("Property advection max iterations"); + property_advection_tolerance = prm.get_double("Property advection tolerance"); + property_advection_max_iterations = prm.get_integer ("Property advection max iterations"); - const std::string temp_cpo_derivative_algorithm = prm.get("CPO derivatives algorithm"); + const std::string temp_cpo_derivative_algorithm = prm.get("CPO derivatives algorithm"); - if (temp_cpo_derivative_algorithm == "Spin tensor") + if (temp_cpo_derivative_algorithm == "Spin tensor") + { + cpo_derivative_algorithm = CPODerivativeAlgorithm::spin_tensor; + } + else if (temp_cpo_derivative_algorithm == "D-Rex 2004") + { + cpo_derivative_algorithm = CPODerivativeAlgorithm::drex_2004; + } + else + { + AssertThrow(false, + ExcMessage("The CPO derivatives algorithm needs to be one of the following: " + "Spin tensor, D-Rex 2004.")); + } + + const std::string temp_advection_method = prm.get("Property advection method"); + if (temp_advection_method == "Forward Euler") + { + advection_method = AdvectionMethod::forward_euler; + } + else if (temp_advection_method == "Backward Euler") + { + advection_method = AdvectionMethod::backward_euler; + } + else + { + AssertThrow(false, ExcMessage("particle property advection method not found: \"" + temp_advection_method + "\"")); + } + + prm.enter_subsection("Initial grains"); + { + const std::string model_name = prm.get("Model name"); + if (model_name == "Uniform grains and random uniform rotations") { - cpo_derivative_algorithm = CPODerivativeAlgorithm::spin_tensor; + initial_grains_model = CPOInitialGrainsModel::uniform_grains_and_random_uniform_rotations; } - else if (temp_cpo_derivative_algorithm == "D-Rex 2004") + else if (model_name == "World Builder") { - cpo_derivative_algorithm = CPODerivativeAlgorithm::drex_2004; + initial_grains_model = CPOInitialGrainsModel::world_builder; } else { AssertThrow(false, - ExcMessage("The CPO derivatives algorithm needs to be one of the following: " - "Spin tensor, D-Rex 2004.")); + ExcMessage("No model named " + model_name + "for CPO particle property initialization. " + + "Only the model \"Uniform grains and random uniform rotations\" and " + "\"World Builder\" are available.")); } - const std::string temp_advection_method = prm.get("Property advection method"); - if (temp_advection_method == "Forward Euler") - { - advection_method = AdvectionMethod::forward_euler; - } - else if (temp_advection_method == "Backward Euler") + const std::vector temp_deformation_type_selector = dealii::Utilities::split_string_list(prm.get("Minerals")); + n_minerals = temp_deformation_type_selector.size(); + deformation_type_selector.resize(n_minerals); + + for (size_t mineral_i = 0; mineral_i < n_minerals; ++mineral_i) { - advection_method = AdvectionMethod::backward_euler; + if (temp_deformation_type_selector[mineral_i] == "Passive") + { + deformation_type_selector[mineral_i] = DeformationTypeSelector::passive; + } + else if (temp_deformation_type_selector[mineral_i] == "Olivine: Karato 2008") + { + deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_karato_2008; + } + else if (temp_deformation_type_selector[mineral_i] == "Olivine: A-fabric") + { + deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_a_fabric; + } + else if (temp_deformation_type_selector[mineral_i] == "Olivine: B-fabric") + { + deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_b_fabric; + } + else if (temp_deformation_type_selector[mineral_i] == "Olivine: C-fabric") + { + deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_c_fabric; + } + else if (temp_deformation_type_selector[mineral_i] == "Olivine: D-fabric") + { + deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_d_fabric; + } + else if (temp_deformation_type_selector[mineral_i] == "Olivine: E-fabric") + { + deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_e_fabric; + } + else if (temp_deformation_type_selector[mineral_i] == "Enstatite") + { + deformation_type_selector[mineral_i] = DeformationTypeSelector::enstatite; + } + else + { + AssertThrow(false, + ExcMessage("The fabric needs to be assigned one of the following comma-delimited values: Olivine: Karato 2008, " + "Olivine: A-fabric, Olivine: B-fabric, Olivine: C-fabric, Olivine: D-fabric," + "Olivine: E-fabric, Enstatite, Passive.")); + } } - else + + volume_fractions_minerals = Utilities::string_to_double(dealii::Utilities::split_string_list(prm.get("Volume fractions minerals"))); + double volume_fractions_minerals_sum = 0; + for (auto fraction : volume_fractions_minerals) { - AssertThrow(false, ExcMessage("particle property advection method not found: \"" + temp_advection_method + "\"")); + volume_fractions_minerals_sum += fraction; } - prm.enter_subsection("Initial grains"); - { - const std::string model_name = prm.get("Model name"); - if (model_name == "Uniform grains and random uniform rotations") - { - initial_grains_model = CPOInitialGrainsModel::uniform_grains_and_random_uniform_rotations; - } - else if (model_name == "World Builder") - { - initial_grains_model = CPOInitialGrainsModel::world_builder; - } - else - { - AssertThrow(false, - ExcMessage("No model named " + model_name + "for CPO particle property initialization. " - + "Only the model \"Uniform grains and random uniform rotations\" and " - "\"World Builder\" are available.")); - } - - const std::vector temp_deformation_type_selector = dealii::Utilities::split_string_list(prm.get("Minerals")); - n_minerals = temp_deformation_type_selector.size(); - deformation_type_selector.resize(n_minerals); - - for (size_t mineral_i = 0; mineral_i < n_minerals; ++mineral_i) - { - if (temp_deformation_type_selector[mineral_i] == "Passive") - { - deformation_type_selector[mineral_i] = DeformationTypeSelector::passive; - } - else if (temp_deformation_type_selector[mineral_i] == "Olivine: Karato 2008") - { - deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_karato_2008; - } - else if (temp_deformation_type_selector[mineral_i] == "Olivine: A-fabric") - { - deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_a_fabric; - } - else if (temp_deformation_type_selector[mineral_i] == "Olivine: B-fabric") - { - deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_b_fabric; - } - else if (temp_deformation_type_selector[mineral_i] == "Olivine: C-fabric") - { - deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_c_fabric; - } - else if (temp_deformation_type_selector[mineral_i] == "Olivine: D-fabric") - { - deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_d_fabric; - } - else if (temp_deformation_type_selector[mineral_i] == "Olivine: E-fabric") - { - deformation_type_selector[mineral_i] = DeformationTypeSelector::olivine_e_fabric; - } - else if (temp_deformation_type_selector[mineral_i] == "Enstatite") - { - deformation_type_selector[mineral_i] = DeformationTypeSelector::enstatite; - } - else - { - AssertThrow(false, - ExcMessage("The fabric needs to be assigned one of the following comma-delimited values: Olivine: Karato 2008, " - "Olivine: A-fabric, Olivine: B-fabric, Olivine: C-fabric, Olivine: D-fabric," - "Olivine: E-fabric, Enstatite, Passive.")); - } - } - - volume_fractions_minerals = Utilities::string_to_double(dealii::Utilities::split_string_list(prm.get("Volume fractions minerals"))); - double volume_fractions_minerals_sum = 0; - for (auto fraction : volume_fractions_minerals) - { - volume_fractions_minerals_sum += fraction; - } - - AssertThrow(abs(volume_fractions_minerals_sum-1.0) < 2.0 * std::numeric_limits::epsilon(), - ExcMessage("The sum of the CPO volume fractions should be one.")); - } - prm.leave_subsection(); + AssertThrow(abs(volume_fractions_minerals_sum-1.0) < 2.0 * std::numeric_limits::epsilon(), + ExcMessage("The sum of the CPO volume fractions should be one.")); + } + prm.leave_subsection(); - prm.enter_subsection("D-Rex 2004"); - { - mobility = prm.get_double("Mobility"); - volume_fractions_minerals = Utilities::string_to_double(dealii::Utilities::split_string_list(prm.get("Volume fractions minerals"))); - stress_exponent = prm.get_double("Stress exponents"); - exponent_p = prm.get_double("Exponents p"); - nucleation_efficiency = prm.get_double("Nucleation efficiency"); - threshold_GBS = prm.get_double("Threshold GBS"); - } - prm.leave_subsection(); + prm.enter_subsection("D-Rex 2004"); + { + mobility = prm.get_double("Mobility"); + volume_fractions_minerals = Utilities::string_to_double(dealii::Utilities::split_string_list(prm.get("Volume fractions minerals"))); + stress_exponent = prm.get_double("Stress exponents"); + exponent_p = prm.get_double("Exponents p"); + nucleation_efficiency = prm.get_double("Nucleation efficiency"); + threshold_GBS = prm.get_double("Threshold GBS"); } - prm.leave_subsection (); + prm.leave_subsection(); } prm.leave_subsection (); } diff --git a/source/particle/property/function.cc b/source/particle/property/function.cc index 09653821cb7..d88dd252001 100644 --- a/source/particle/property/function.cc +++ b/source/particle/property/function.cc @@ -54,17 +54,13 @@ namespace aspect void Function::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Function"); { - prm.enter_subsection("Function"); - { - prm.declare_entry ("Number of components", "1", - Patterns::Integer (0), - "The number of function components where each component is described " - "by a function expression delimited by a ';'."); - Functions::ParsedFunction::declare_parameters (prm, 1); - } - prm.leave_subsection(); + prm.declare_entry ("Number of components", "1", + Patterns::Integer (0), + "The number of function components where each component is described " + "by a function expression delimited by a ';'."); + Functions::ParsedFunction::declare_parameters (prm, 1); } prm.leave_subsection(); } @@ -74,25 +70,21 @@ namespace aspect void Function::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); - { - prm.enter_subsection("Function"); - n_components = prm.get_integer ("Number of components"); - try - { - function = std::make_unique>(n_components); - function->parse_parameters (prm); - } - catch (...) - { - std::cerr << "ERROR: FunctionParser failed to parse\n" - << "\t'Particles.Function'\n" - << "with expression\n" - << "\t'" << prm.get("Function expression") << "'"; - throw; - } - prm.leave_subsection(); - } + prm.enter_subsection("Function"); + n_components = prm.get_integer ("Number of components"); + try + { + function = std::make_unique>(n_components); + function->parse_parameters (prm); + } + catch (...) + { + std::cerr << "ERROR: FunctionParser failed to parse\n" + << "\t'Particles.Function'\n" + << "with expression\n" + << "\t'" << prm.get("Function expression") << "'"; + throw; + } prm.leave_subsection(); } } diff --git a/source/particle/property/interface.cc b/source/particle/property/interface.cc index e9a7d89ad68..8c68cebec0c 100644 --- a/source/particle/property/interface.cc +++ b/source/particle/property/interface.cc @@ -267,22 +267,18 @@ namespace aspect IntegratorProperties::parse_parameters (ParameterHandler &prm) { std::string name; - prm.enter_subsection ("Particles"); - { - name = prm.get ("Integration scheme"); + name = prm.get ("Integration scheme"); - if (name == "rk2") - n_integrator_properties = Particle::Integrator::RK2::n_integrator_properties; - else if (name == "rk4") - n_integrator_properties = Particle::Integrator::RK4::n_integrator_properties; - else if (name == "euler") - n_integrator_properties = Particle::Integrator::Euler::n_integrator_properties; - else - AssertThrow(false, - ExcMessage("Unknown integrator scheme. The particle property 'Integrator properties' " - "does not know how many particle properties to store for this integration scheme.")); - } - prm.leave_subsection (); + if (name == "rk2") + n_integrator_properties = Particle::Integrator::RK2::n_integrator_properties; + else if (name == "rk4") + n_integrator_properties = Particle::Integrator::RK4::n_integrator_properties; + else if (name == "euler") + n_integrator_properties = Particle::Integrator::Euler::n_integrator_properties; + else + AssertThrow(false, + ExcMessage("Unknown integrator scheme. The particle property 'Integrator properties' " + "does not know how many particle properties to store for this integration scheme.")); } @@ -659,23 +655,20 @@ namespace aspect void Manager::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); - { - // finally also construct a string for Patterns::MultipleSelection that - // contains the names of all registered particle properties - const std::string pattern_of_names - = std::get(registered_plugins).get_pattern_of_names (); - prm.declare_entry("List of particle properties", - "", - Patterns::MultipleSelection(pattern_of_names), - "A comma separated list of particle properties that should be tracked. " - "By default none is selected, which means only position, velocity " - "and id of the particles are output. \n\n" - "The following properties are available:\n\n" - + - std::get(registered_plugins).get_description_string()); - } - prm.leave_subsection(); + // finally also construct a string for Patterns::MultipleSelection that + // contains the names of all registered particle properties + const std::string pattern_of_names + = std::get(registered_plugins).get_pattern_of_names (); + + prm.declare_entry("List of particle properties", + "", + Patterns::MultipleSelection(pattern_of_names), + "A comma separated list of particle properties that should be tracked. " + "By default none is selected, which means only position, velocity " + "and id of the particles are output. \n\n" + "The following properties are available:\n\n" + + + std::get(registered_plugins).get_description_string()); // now declare the parameters of each of the registered // particle properties in turn @@ -691,29 +684,25 @@ namespace aspect Assert (std::get(registered_plugins).plugins != nullptr, ExcMessage ("No postprocessors registered!?")); - prm.enter_subsection("Particles"); - { - // now also see which derived quantities we are to compute - plugin_names = Utilities::split_string_list(prm.get("List of particle properties")); - AssertThrow(Utilities::has_unique_entries(plugin_names), - ExcMessage("The list of strings for the parameter " - "'Particles/List of particle properties' contains entries more than once. " - "This is not allowed. Please check your parameter file.")); - - // see if 'all' was selected (or is part of the list). if so - // simply replace the list with one that contains all names - if (std::find (plugin_names.begin(), - plugin_names.end(), - "all") != plugin_names.end()) - { - plugin_names.clear(); - for (typename std::list>::PluginInfo>::const_iterator - p = std::get(registered_plugins).plugins->begin(); - p != std::get(registered_plugins).plugins->end(); ++p) - plugin_names.push_back (std::get<0>(*p)); - } - } - prm.leave_subsection(); + // now also see which derived quantities we are to compute + plugin_names = Utilities::split_string_list(prm.get("List of particle properties")); + AssertThrow(Utilities::has_unique_entries(plugin_names), + ExcMessage("The list of strings for the parameter " + "'Particles/List of particle properties' contains entries more than once. " + "This is not allowed. Please check your parameter file.")); + + // see if 'all' was selected (or is part of the list). if so + // simply replace the list with one that contains all names + if (std::find (plugin_names.begin(), + plugin_names.end(), + "all") != plugin_names.end()) + { + plugin_names.clear(); + for (typename std::list>::PluginInfo>::const_iterator + p = std::get(registered_plugins).plugins->begin(); + p != std::get(registered_plugins).plugins->end(); ++p) + plugin_names.push_back (std::get<0>(*p)); + } // then go through the list, create objects and let them parse // their own parameters diff --git a/source/particle/property/melt_particle.cc b/source/particle/property/melt_particle.cc index 48e2f53c207..fa80b32bee3 100644 --- a/source/particle/property/melt_particle.cc +++ b/source/particle/property/melt_particle.cc @@ -81,17 +81,13 @@ namespace aspect void MeltParticle::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Melt particle"); { - prm.enter_subsection("Melt particle"); - { - prm.declare_entry ("Threshold for melt presence", "1e-3", - Patterns::Double (0., 1.), - "The minimum porosity that has to be present at the position of a particle " - "for it to be considered a melt particle (in the sense that the melt presence " - "property is set to 1)."); - } - prm.leave_subsection(); + prm.declare_entry ("Threshold for melt presence", "1e-3", + Patterns::Double (0., 1.), + "The minimum porosity that has to be present at the position of a particle " + "for it to be considered a melt particle (in the sense that the melt presence " + "property is set to 1)."); } prm.leave_subsection(); } @@ -101,13 +97,9 @@ namespace aspect void MeltParticle::parse_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); + prm.enter_subsection("Melt particle"); { - prm.enter_subsection("Melt particle"); - { - threshold_for_melt_presence = prm.get_double ("Threshold for melt presence"); - } - prm.leave_subsection(); + threshold_for_melt_presence = prm.get_double ("Threshold for melt presence"); } prm.leave_subsection(); } diff --git a/source/particle/world.cc b/source/particle/world.cc index 918b6ea4920..64531651b92 100644 --- a/source/particle/world.cc +++ b/source/particle/world.cc @@ -1235,13 +1235,15 @@ namespace aspect "particles in ghost cells need to be exchanged between the " "processes neighboring this cell. This parameter determines " "whether this transport is happening."); + + Generator::declare_parameters(prm); + Integrator::declare_parameters(prm); + Interpolator::declare_parameters(prm); + + Property::Manager::declare_parameters(prm); } prm.leave_subsection (); - Generator::declare_parameters(prm); - Integrator::declare_parameters(prm); - Interpolator::declare_parameters(prm); - Property::Manager::declare_parameters(prm); } @@ -1311,38 +1313,39 @@ namespace aspect "are listed in the corresponding manual subsection.")); } - } - prm.leave_subsection (); - TimerOutput::Scope timer_section(this->get_computing_timer(), "Particles: Initialization"); + TimerOutput::Scope timer_section(this->get_computing_timer(), "Particles: Initialization"); - // Create a generator object depending on what the parameters specify - generator = Generator::create_particle_generator (prm); - if (SimulatorAccess *sim = dynamic_cast*>(generator.get())) - sim->initialize_simulator (this->get_simulator()); - generator->parse_parameters(prm); - generator->initialize(); - - // Create a property_manager object and initialize its properties - property_manager = std::make_unique> (); - SimulatorAccess *sim = dynamic_cast*>(property_manager.get()); - sim->initialize_simulator (this->get_simulator()); - property_manager->parse_parameters(prm); - property_manager->initialize(); - - // Create an integrator object depending on the specified parameter - integrator = Integrator::create_particle_integrator (prm); - if (SimulatorAccess *sim = dynamic_cast*>(integrator.get())) - sim->initialize_simulator (this->get_simulator()); - integrator->parse_parameters(prm); - integrator->initialize(); + // Create a generator object depending on what the parameters specify + generator = Generator::create_particle_generator (prm); + if (SimulatorAccess *sim = dynamic_cast*>(generator.get())) + sim->initialize_simulator (this->get_simulator()); + generator->parse_parameters(prm); + generator->initialize(); - // Create an interpolator object depending on the specified parameter - interpolator = Interpolator::create_particle_interpolator (prm); - if (SimulatorAccess *sim = dynamic_cast*>(interpolator.get())) + // Create a property_manager object and initialize its properties + property_manager = std::make_unique> (); + SimulatorAccess *sim = dynamic_cast*>(property_manager.get()); sim->initialize_simulator (this->get_simulator()); - interpolator->parse_parameters(prm); - interpolator->initialize(); + property_manager->parse_parameters(prm); + property_manager->initialize(); + + // Create an integrator object depending on the specified parameter + integrator = Integrator::create_particle_integrator (prm); + if (SimulatorAccess *sim = dynamic_cast*>(integrator.get())) + sim->initialize_simulator (this->get_simulator()); + integrator->parse_parameters(prm); + integrator->initialize(); + + // Create an interpolator object depending on the specified parameter + interpolator = Interpolator::create_particle_interpolator (prm); + if (SimulatorAccess *sim = dynamic_cast*>(interpolator.get())) + sim->initialize_simulator (this->get_simulator()); + interpolator->parse_parameters(prm); + interpolator->initialize(); + + } + prm.leave_subsection (); } } } diff --git a/unit_tests/crystal_preferred_orientation.cc b/unit_tests/crystal_preferred_orientation.cc index 73fb9343646..d379e32bb63 100644 --- a/unit_tests/crystal_preferred_orientation.cc +++ b/unit_tests/crystal_preferred_orientation.cc @@ -128,15 +128,16 @@ TEST_CASE("CPO core: Store and Load") // data position = 1. aspect::Particle::Property::CrystalPreferredOrientation<3> cpo; aspect::ParameterHandler prm; - cpo.declare_parameters(prm); prm.enter_subsection("Particles"); { + cpo.declare_parameters(prm); prm.enter_subsection("Crystal Preferred Orientation"); { prm.set("Random number seed","1"); prm.set("Number of grains per particle","3"); prm.set("CPO derivatives algorithm","Spin tensor"); prm.set("Property advection method","Backward Euler"); + prm.enter_subsection("Initial grains"); { prm.set("Model name","Uniform grains and random uniform rotations"); @@ -151,7 +152,12 @@ TEST_CASE("CPO core: Store and Load") } prm.leave_subsection (); - cpo.parse_parameters(prm); + prm.enter_subsection("Particles"); + { + cpo.parse_parameters(prm); + } + prm.leave_subsection (); + cpo.initialize(); unsigned int cpo_data_position = 1; @@ -304,9 +310,9 @@ TEST_CASE("CPO core: Spin tensor") aspect::Particle::Property::CrystalPreferredOrientation<3> cpo_3d; aspect::ParameterHandler prm; - cpo_3d.declare_parameters(prm); prm.enter_subsection("Particles"); { + cpo_3d.declare_parameters(prm); prm.enter_subsection("Crystal Preferred Orientation"); { prm.set("Random number seed","1"); @@ -327,7 +333,13 @@ TEST_CASE("CPO core: Spin tensor") } prm.leave_subsection (); - cpo_3d.parse_parameters(prm); + + prm.enter_subsection("Particles"); + { + cpo_3d.parse_parameters(prm); + } + prm.leave_subsection (); + cpo_3d.initialize(); Point<3> dummy_point; @@ -605,10 +617,10 @@ TEST_CASE("CPO") Particle::Property::CrystalPreferredOrientation lpo_3d; ParameterHandler prm; - lpo_3d.declare_parameters(prm); prm.enter_subsection("Particles"); { + lpo_3d.declare_parameters(prm); prm.enter_subsection("Crystal Preferred Orientation"); { prm.set("Random number seed","1"); @@ -618,7 +630,12 @@ TEST_CASE("CPO") } prm.leave_subsection (); - lpo_3d.parse_parameters(prm); + prm.enter_subsection("Particles"); + { + lpo_3d.parse_parameters(prm); + } + prm.leave_subsection(); + lpo_3d.initialize(); @@ -812,10 +829,10 @@ TEST_CASE("CPO") Particle::Property::CrystalPreferredOrientation lpo_3d; ParameterHandler prm; - lpo_3d.declare_parameters(prm); prm.enter_subsection("Particles"); { + lpo_3d.declare_parameters(prm); prm.enter_subsection("Crystal Preferred Orientation"); { prm.set("Random number seed","1"); @@ -825,7 +842,12 @@ TEST_CASE("CPO") } prm.leave_subsection (); - lpo_3d.parse_parameters(prm); + prm.enter_subsection("Particles"); + { + lpo_3d.parse_parameters(prm); + } + prm.leave_subsection (); + lpo_3d.initialize(); @@ -1069,10 +1091,10 @@ TEST_CASE("CPO elastic tensor") aspect::Particle::Property::CrystalPreferredOrientation<3> cpo; aspect::Particle::Property::CpoElasticTensor<3> cpo_elastic_tensor; aspect::ParameterHandler prm; - cpo.declare_parameters(prm); - cpo_elastic_tensor.declare_parameters(prm); prm.enter_subsection("Particles"); { + cpo.declare_parameters(prm); + cpo_elastic_tensor.declare_parameters(prm); prm.enter_subsection("Crystal Preferred Orientation"); { prm.set("Random number seed","1"); @@ -1093,10 +1115,15 @@ TEST_CASE("CPO elastic tensor") } prm.leave_subsection (); - cpo.parse_parameters(prm); + prm.enter_subsection("Particles"); + { + cpo.parse_parameters(prm); + cpo_elastic_tensor.parse_parameters(prm); + } + prm.leave_subsection(); + cpo.initialize(); - cpo_elastic_tensor.parse_parameters(prm); // All these numbers are directly from the Fortran D-Rex // Had to fix the random seed to get consistent results. diff --git a/unit_tests/particles.cc b/unit_tests/particles.cc index fc27ec44b0d..8cff8cea568 100644 --- a/unit_tests/particles.cc +++ b/unit_tests/particles.cc @@ -26,14 +26,15 @@ TEST_CASE("Particle Manager plugin names") { dealii::ParameterHandler prm; + aspect::Particle::Property::Manager<2> manager; // The property manager needs to know about the integrator, which is declared in World aspect::Particle::World<2>::declare_parameters(prm); - aspect::Particle::Property::Manager<2> manager; - manager.declare_parameters(prm); + prm.enter_subsection("Particles"); + manager.declare_parameters(prm); prm.set("List of particle properties","composition, position"); - prm.leave_subsection(); manager.parse_parameters(prm); + prm.leave_subsection(); // existing and listed pluring REQUIRE(manager.plugin_name_exists("composition") == true);