From 0cab1d0085a743e71804cd3d727ff2aa484065ae Mon Sep 17 00:00:00 2001 From: Rene Gassmoeller Date: Fri, 23 Jun 2017 12:40:36 -0600 Subject: [PATCH] Use position hash as pseudo-random seed --- .../initial_composition/random_perturbation.h | 9 ++++ .../initial_temperature/random_perturbation.h | 9 ++++ .../random_perturbation.cc | 49 ++++++++++------- .../random_perturbation.cc | 44 +++++++++------ tests/random_composition_perturbation.prm | 53 +++++++------------ .../screen-output | 2 +- .../statistics | 2 +- tests/random_temperature_perturbation.prm | 45 ++++++---------- .../screen-output | 2 +- .../statistics | 2 +- 10 files changed, 115 insertions(+), 102 deletions(-) diff --git a/include/aspect/initial_composition/random_perturbation.h b/include/aspect/initial_composition/random_perturbation.h index f2acffc3acb..21593497d2b 100644 --- a/include/aspect/initial_composition/random_perturbation.h +++ b/include/aspect/initial_composition/random_perturbation.h @@ -77,6 +77,15 @@ namespace aspect * Random number generator. */ mutable boost::mt19937 random_number_generator; + + /** + * Whether to use a random seed for the random + * number generator. This parameter controls whether + * this plugin generates different or identical + * perturbations for subsequent model runs of + * the same setup. + */ + bool use_random_seed; }; } } diff --git a/include/aspect/initial_temperature/random_perturbation.h b/include/aspect/initial_temperature/random_perturbation.h index fdab2296133..9dae3a8c9af 100644 --- a/include/aspect/initial_temperature/random_perturbation.h +++ b/include/aspect/initial_temperature/random_perturbation.h @@ -76,6 +76,15 @@ namespace aspect * Random number generator. */ mutable boost::mt19937 random_number_generator; + + /** + * Whether to use a random seed for the random + * number generator. This parameter controls whether + * this plugin generates different or identical + * perturbations for subsequent model runs of + * the same setup. + */ + bool use_random_seed; }; } } diff --git a/source/initial_composition/random_perturbation.cc b/source/initial_composition/random_perturbation.cc index 50a56b1ee16..527077df25f 100644 --- a/source/initial_composition/random_perturbation.cc +++ b/source/initial_composition/random_perturbation.cc @@ -21,23 +21,44 @@ #include +#include #include namespace aspect { namespace InitialComposition { + namespace + { + template + std::size_t point_hash(const Point &position) + { + std::size_t hash; + + for (unsigned int i = 0; i < dim; ++i) + boost::hash_combine(hash,position[i]); + + return hash; + } + } + template double RandomPerturbation:: - initial_composition (const Point &/*position*/, - const unsigned int /*compositional_index*/) const + initial_composition (const Point &position, + const unsigned int compositional_index) const { - // Uniform distribution on the interval [0,1]. This - // will be used to generate the random composition perturbation. - boost::uniform_01 uniform_distribution_01; + std::size_t seed = point_hash(position); + boost::hash_combine(seed,compositional_index); + if (use_random_seed) + boost::hash_combine(seed,time(NULL)); + + random_number_generator.seed(seed); - return magnitude * 2.0 * (uniform_distribution_01(random_number_generator) - 0.5); + // Uniform distribution on the interval [-magnitude,magnitude). This + // will be used to generate the random composition perturbation. + boost::random::uniform_real_distribution uniform_distribution(-magnitude,magnitude); + return uniform_distribution(random_number_generator); } template @@ -56,14 +77,8 @@ namespace aspect "Whether to use a random seed for the random " "number generator. This parameter controls whether " "this plugin generates different or identical " - "perturbations for different model runs."); - prm.declare_entry ("Random seed", "5432", - Patterns::Integer(0), - "The initial seed for the random perturbation. If " - "'Use random seed' is set to 'false' model runs " - "with identical seed will lead to identical " - "perturbations, while model runs with different " - "seeds will generate different perturbations."); + "perturbations for subsequent model runs of" + "the same setup."); } prm.leave_subsection (); } @@ -80,11 +95,7 @@ namespace aspect prm.enter_subsection("Random perturbation"); { magnitude = prm.get_double ("Magnitude"); - - if (prm.get_bool("Use random seed")) - random_number_generator.seed(time(NULL)); - else - random_number_generator.seed(prm.get_integer("Random seed")); + use_random_seed = prm.get_bool("Use random seed"); } prm.leave_subsection (); } diff --git a/source/initial_temperature/random_perturbation.cc b/source/initial_temperature/random_perturbation.cc index 2b3a3b1486e..7958581f5f7 100644 --- a/source/initial_temperature/random_perturbation.cc +++ b/source/initial_temperature/random_perturbation.cc @@ -21,22 +21,43 @@ #include +#include #include namespace aspect { namespace InitialTemperature { + namespace + { + template + std::size_t point_hash(const Point &position) + { + std::size_t hash; + + for (unsigned int i = 0; i < dim; ++i) + boost::hash_combine(hash,position[i]); + + return hash; + } + } + template double RandomPerturbation:: - initial_temperature (const Point &/*position*/) const + initial_temperature (const Point &position) const { - // Uniform distribution on the interval [0,1]. This - // will be used to generate the random temperature perturbation. - boost::uniform_01 uniform_distribution_01; + std::size_t seed = point_hash(position); + + if (use_random_seed) + boost::hash_combine(seed,time(NULL)); - return magnitude * 2.0 * (uniform_distribution_01(random_number_generator) - 0.5); + random_number_generator.seed(seed); + + // Uniform distribution on the interval [-magnitude,magnitude). This + // will be used to generate the random temperature perturbation. + boost::random::uniform_real_distribution uniform_distribution(-magnitude,magnitude); + return uniform_distribution(random_number_generator); } template @@ -56,13 +77,6 @@ namespace aspect "number generator. This parameter controls whether " "this plugin generates different or identical " "perturbations for different model runs."); - prm.declare_entry ("Random seed", "5432", - Patterns::Integer(0), - "The initial seed for the random perturbation. If " - "'Use random seed' is set to 'false' model runs " - "with identical seed will lead to identical " - "perturbations, while model runs with different " - "seeds will generate different perturbations."); } prm.leave_subsection (); } @@ -79,11 +93,7 @@ namespace aspect prm.enter_subsection("Random perturbation"); { magnitude = prm.get_double ("Magnitude"); - - if (prm.get_bool("Use random seed")) - random_number_generator.seed(time(NULL)); - else - random_number_generator.seed(prm.get_integer("Random seed")); + use_random_seed = prm.get_bool("Use random seed"); } prm.leave_subsection (); } diff --git a/tests/random_composition_perturbation.prm b/tests/random_composition_perturbation.prm index e23c5c681bd..6852e5721cd 100644 --- a/tests/random_composition_perturbation.prm +++ b/tests/random_composition_perturbation.prm @@ -1,43 +1,45 @@ -# Test to check the status of the random initial temperature perturbation +# Test to check the status of the random initial composition perturbation # plugin. -set End time = 0 +subsection Model settings + set Tangential velocity boundary indicators = left, right, bottom, top +end -subsection Boundary temperature model - set List of model names = box +subsection Mesh refinement + set Initial global refinement = 3 end +subsection Postprocess + set List of postprocessors = composition statistics +end -subsection Gravity model - set Model name = vertical +subsection Compositional fields + set Number of fields = 2 end +subsection Material model + set Model name = simpler +end +set End time = 0 subsection Geometry model set Model name = box - - subsection Box - set X extent = 1 - set Y extent = 1 - end end +subsection Gravity model + set Model name = vertical +end subsection Initial temperature model set List of model names = function - subsection Function set Function expression = 0.5 end -end -subsection Compositional fields - set Number of fields = 2 end subsection Initial composition model set List of model names = function, random perturbation - subsection Random perturbation set Magnitude = 0.2 end @@ -45,25 +47,10 @@ subsection Initial composition model subsection Function set Function expression = 0.5;0.0 end -end - -subsection Material model - set Model name = simpler end - -subsection Mesh refinement - set Initial adaptive refinement = 0 - set Initial global refinement = 3 -end - - -subsection Model settings - set Tangential velocity boundary indicators = left, right, bottom, top -end - -subsection Postprocess - set List of postprocessors = composition statistics +subsection Boundary temperature model + set List of model names = box end diff --git a/tests/random_composition_perturbation/screen-output b/tests/random_composition_perturbation/screen-output index a8a8dc6da65..1a746fdca3b 100644 --- a/tests/random_composition_perturbation/screen-output +++ b/tests/random_composition_perturbation/screen-output @@ -10,7 +10,7 @@ Number of degrees of freedom: 1,526 (578+81+289+289+289) Solving Stokes system... 2+0 iterations. Postprocessing: - Compositions min/max/mass: 0.3001/0.6984/0.4938 // -0.2/0.1996/-0.01184 + Compositions min/max/mass: 0.3002/0.6997/0.5069 // -0.199/0.1999/-0.007404 Termination requested by criterion: end time diff --git a/tests/random_composition_perturbation/statistics b/tests/random_composition_perturbation/statistics index 992b20ca031..ad7b7e757d9 100644 --- a/tests/random_composition_perturbation/statistics +++ b/tests/random_composition_perturbation/statistics @@ -17,4 +17,4 @@ # 17: Minimal value for composition C_2 # 18: Maximal value for composition C_2 # 19: Global mass for composition C_2 -0 0.000000000000e+00 0.000000000000e+00 64 659 289 578 0 0 0 2 3 2 3.00090365e-01 6.98414874e-01 4.93781411e-01 -1.99952361e-01 1.99564844e-01 -1.18366501e-02 +0 0.000000000000e+00 0.000000000000e+00 64 659 289 578 0 0 0 2 3 2 3.00222459e-01 6.99744700e-01 5.06886136e-01 -1.99012748e-01 1.99867409e-01 -7.40357014e-03 diff --git a/tests/random_temperature_perturbation.prm b/tests/random_temperature_perturbation.prm index 46412b2ae62..52afa7b456a 100644 --- a/tests/random_temperature_perturbation.prm +++ b/tests/random_temperature_perturbation.prm @@ -1,31 +1,33 @@ # Test to check the status of the random initial temperature perturbation # plugin. -set End time = 0 - -subsection Boundary temperature model - set List of model names = box +subsection Model settings + set Tangential velocity boundary indicators = left, right, bottom, top end +subsection Mesh refinement + set Initial global refinement = 3 +end -subsection Gravity model - set Model name = vertical +subsection Postprocess + set List of postprocessors = temperature statistics end +subsection Material model + set Model name = simpler +end +set End time = 0 subsection Geometry model set Model name = box - - subsection Box - set X extent = 1 - set Y extent = 1 - end end +subsection Gravity model + set Model name = vertical +end subsection Initial temperature model set List of model names = function, random perturbation - subsection Random perturbation set Magnitude = 0.2 end @@ -33,25 +35,10 @@ subsection Initial temperature model subsection Function set Function expression = 0.5 end -end - - -subsection Material model - set Model name = simpler -end - - -subsection Mesh refinement - set Initial adaptive refinement = 0 - set Initial global refinement = 3 -end - -subsection Model settings - set Tangential velocity boundary indicators = left, right, bottom, top end -subsection Postprocess - set List of postprocessors = temperature statistics +subsection Boundary temperature model + set List of model names = box end diff --git a/tests/random_temperature_perturbation/screen-output b/tests/random_temperature_perturbation/screen-output index 88bdd9e8546..0750ac468f2 100644 --- a/tests/random_temperature_perturbation/screen-output +++ b/tests/random_temperature_perturbation/screen-output @@ -8,7 +8,7 @@ Number of degrees of freedom: 948 (578+81+289) Solving Stokes system... 17+0 iterations. Postprocessing: - Temperature min/avg/max: 0.3001 K, 0.5056 K, 0.6973 K + Temperature min/avg/max: 0.3002 K, 0.5031 K, 0.6993 K Termination requested by criterion: end time diff --git a/tests/random_temperature_perturbation/statistics b/tests/random_temperature_perturbation/statistics index fa519b561bc..fdbff186729 100644 --- a/tests/random_temperature_perturbation/statistics +++ b/tests/random_temperature_perturbation/statistics @@ -11,4 +11,4 @@ # 11: Minimal temperature (K) # 12: Average temperature (K) # 13: Maximal temperature (K) -0 0.000000000000e+00 0.000000000000e+00 64 659 289 0 17 18 17 3.00129639e-01 5.05619087e-01 6.97305210e-01 +0 0.000000000000e+00 0.000000000000e+00 64 659 289 0 17 18 17 3.00188336e-01 5.03060093e-01 6.99346126e-01