Skip to content

Commit 4e64a68

Browse files
authored
Merge pull request #24 from Geode-solutions/fracture_orientation
feat(SampleAzimuth): modify the segment sampler.
2 parents 807defe + 0a78f4d commit 4e64a68

15 files changed

Lines changed: 221 additions & 26 deletions

File tree

bindings/python/src/stochastic/sampling/direct/double_sampler.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ namespace geode
6060
.def_static( "create_distribution",
6161
&DoubleSampler::create_distribution, pybind11::arg( "desc" ),
6262
"Create a distribution from a description" )
63+
.def_static( "create_rad_angle_distribution_from_degree",
64+
&DoubleSampler::create_rad_angle_distribution_from_degree,
65+
pybind11::arg( "desc" ),
66+
"Create a angle distribution in radian from a description "
67+
"provided in degree" )
6368
.def_static( "sample", &DoubleSampler::sample,
6469
pybind11::arg( "engine" ), pybind11::arg( "dist" ),
6570
"Sample a value from a distribution using a RandomEngine" );

bindings/python/src/stochastic/sampling/distributions.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,17 @@ namespace geode
8787
&TruncatedGaussian::distribution_type_static )
8888
.def( "distribution_type", &TruncatedGaussian::distribution_type )
8989
.def( "string", &TruncatedGaussian::string );
90+
91+
// VonMises
92+
pybind11::class_< VonMises >( module, "VonMises" )
93+
.def( pybind11::init<>() )
94+
.def_readwrite( "mean", &VonMises::mean )
95+
.def_readwrite( "concentration", &VonMises::concentration )
96+
.def( "is_valid", &VonMises::is_valid )
97+
.def_static( "distribution_type_static",
98+
&VonMises::distribution_type_static )
99+
.def( "distribution_type", &VonMises::distribution_type )
100+
.def( "string", &VonMises::string );
90101
}
91102

92103
} // namespace geode

bindings/python/src/stochastic/sampling/random_engine.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ namespace geode
6464
&RandomEngine::sample_truncated_gaussian,
6565
pybind11::arg( "law" ),
6666
"Sample a value from a truncated Gaussian" )
67+
.def( "sample_von_mises", &RandomEngine::sample_von_mises,
68+
pybind11::arg( "law" ),
69+
"Sample a value from a Von Mises-Fisher" )
6770

6871
// Other distributions
6972
.def( "sample_log", &RandomEngine::sample_log,

bindings/python/tests/stochastic/test-py-mh-fractures.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def test_fracture_simulator():
5757
setA.azimuth.max_value = 10.0
5858

5959
# positioning
60-
setA.p20 = 0.1
60+
setA.p20 = 0.06
6161
setA.minimal_spacing = 1.0
6262

6363
runner = stochastic.FractureSimulationRunner(box)
@@ -69,7 +69,7 @@ def test_fracture_simulator():
6969
printer_config.output_folder = os.path.join(printer_config.output_folder , "py_single_fracture_set")
7070

7171
sim_config = stochastic.SimulationConfigurator()
72-
sim_config.realizations = 1000
72+
sim_config.realizations = 500
7373
sim_config.metropolis_hasting_steps = 1000
7474
sim_config.burn_in_steps = 1000
7575
sim_config.printer = printer_config
@@ -97,10 +97,10 @@ def test_two_fracture_sets_simulator():
9797
setA.length.distribution_type = stochastic.DistributionType("UniformClosed")
9898
setA.length.min_value = 1.0
9999
setA.length.max_value = 10.0
100-
setA.azimuth.distribution_type = stochastic.DistributionType("UniformClosed")
101-
setA.azimuth.min_value = 1.0
102-
setA.azimuth.max_value = 10.0
103-
setA.p20 = 0.1
100+
setA.azimuth.distribution_type = stochastic.DistributionType("VonMises")
101+
setA.azimuth.mean = 45
102+
setA.azimuth.standard_deviation = 10.0
103+
setA.p20 = 0.05
104104
setA.minimal_spacing = 1.0
105105

106106
# --- Object set B
@@ -112,7 +112,7 @@ def test_two_fracture_sets_simulator():
112112
setB.azimuth.distribution_type =stochastic.DistributionType("UniformClosed")
113113
setB.azimuth.min_value = 90.0
114114
setB.azimuth.max_value = 100.0
115-
setB.p20 = 0.1
115+
setB.p20 = 0.03
116116
setB.minimal_spacing = 2.0
117117

118118
runner = stochastic.FractureSimulationRunner(box)
@@ -124,7 +124,7 @@ def test_two_fracture_sets_simulator():
124124
printer_config.output_folder = os.path.join(printer_config.output_folder ,printer_config.output_folder, "py_two_fracture_sets")
125125

126126
sim_config = stochastic.SimulationConfigurator()
127-
sim_config.realizations = 1000
127+
sim_config.realizations = 500
128128
sim_config.metropolis_hasting_steps = 1000
129129
sim_config.burn_in_steps = 1000
130130
sim_config.printer = printer_config

include/geode/stochastic/sampling/direct/double_sampler.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ namespace geode
4141
using Distribution = std::variant< UniformClosed< double >,
4242
UniformClosedOpen< double >,
4343
Gaussian,
44-
TruncatedGaussian >;
44+
TruncatedGaussian,
45+
VonMises >;
4546

4647
struct DistributionDescription
4748
{
@@ -84,6 +85,8 @@ namespace geode
8485

8586
static Distribution create_distribution(
8687
const DistributionDescription& desc );
88+
static Distribution create_rad_angle_distribution_from_degree(
89+
const DistributionDescription& angle_desc_deg );
8790

8891
static double sample( RandomEngine& engine, const Distribution& dist );
8992
};

include/geode/stochastic/sampling/direct/object_set_sampler/object_set_sampler.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace geode
4141
{
4242
if( !is_valid_object( obj ) )
4343
{
44+
Logger::warn( "[ObjectSetSampler] - invalid object proposed." );
4445
return LOG_PROB_INVALID;
4546
}
4647
return log_pdf_;

include/geode/stochastic/sampling/direct/object_set_sampler/segment_set_sampler.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ namespace geode
6363
const auto& extremities = obj.vertices();
6464
const auto current =
6565
static_cast< local_index_t >( engine.sample_bernoulli( 0.5 ) );
66+
const auto other = 1 - current;
6667

6768
geode::Sphere< 2 > ball{ extremities[current],
6869
ratio * obj.length() };
@@ -71,7 +72,8 @@ namespace geode
7172
constexpr index_t max_try{ 100 };
7273
for( const auto try_id : geode::Range{ max_try } )
7374
{
74-
if( box_.contains( new_point ) )
75+
if( box_.contains( new_point )
76+
|| box_.contains( extremities[other] ) )
7577
{
7678
OwnerSegment2D new_segment{ obj };
7779
new_segment.set_point( current, new_point );
@@ -91,7 +93,7 @@ namespace geode
9193
const auto& extremities = obj.vertices();
9294

9395
return box_.contains( extremities[0] )
94-
&& box_.contains( extremities[1] );
96+
|| box_.contains( extremities[1] );
9597
}
9698

9799
private:

include/geode/stochastic/sampling/distributions.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,34 @@ namespace geode
176176
}
177177
};
178178

179+
struct opengeode_stochastic_stochastic_api VonMises
180+
{
181+
VonMises() = default;
182+
183+
// 2D von Mises parameters
184+
double mean{ 0.0 }; // mean direction in radians
185+
double concentration{ 1.0 }; // kappa (concentration parameter)
186+
187+
[[nodiscard]] static DistributionType distribution_type_static()
188+
{
189+
return DistributionType{ "VonMises" };
190+
}
191+
192+
[[nodiscard]] DistributionType distribution_type() const
193+
{
194+
return distribution_type_static();
195+
}
196+
197+
[[nodiscard]] bool is_valid() const
198+
{
199+
return concentration >= 0.0 && std::isfinite( mean );
200+
}
201+
202+
std::string string() const
203+
{
204+
return absl::StrCat( distribution_type().get(), "(mean=", mean,
205+
", kappa=", concentration, ")" );
206+
}
207+
};
208+
179209
} // namespace geode

include/geode/stochastic/sampling/mcmc/helpers/fracture_simulation_runner.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ namespace geode
9797
auto length_distribution =
9898
DoubleSampler::create_distribution( set_desc.length );
9999
auto azimuth_distribution =
100-
DoubleSampler::create_distribution( set_desc.azimuth );
100+
DoubleSampler::create_rad_angle_distribution_from_degree(
101+
set_desc.azimuth );
101102
this->set_samplers_.push_back(
102103
std::make_unique< UniformSegmentSetSampler >(
103104
box_, length_distribution, azimuth_distribution ) );

include/geode/stochastic/sampling/random_engine.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ namespace geode
5050

5151
double sample_gaussian( const Gaussian& law );
5252
double sample_truncated_gaussian( const TruncatedGaussian& law );
53+
double sample_von_mises( const VonMises& law );
5354

5455
double sample_log();
5556

0 commit comments

Comments
 (0)