Skip to content

Commit 02e206d

Browse files
feat(SpatialDomain): account for edge effects
1 parent a14d16e commit 02e206d

10 files changed

Lines changed: 76 additions & 46 deletions

File tree

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

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,60 +28,72 @@
2828

2929
#include <geode/stochastic/sampling/direct/object_set_sampler/object_set_sampler.hpp>
3030
#include <geode/stochastic/sampling/direct/point_uniform_sampler.hpp>
31+
#include <geode/stochastic/spatial/spatial_domain.hpp>
3132

3233
namespace geode
3334
{
3435
template < index_t dimension >
3536
class UniformPointSetSampler : public ObjectSetSampler< Point< dimension > >
3637
{
3738
public:
38-
UniformPointSetSampler( const BoundingBox< dimension >& box )
39-
: ObjectSetSampler< Point< dimension > >{}, box_( box )
39+
UniformPointSetSampler( const SpatialDomain< dimension >& domain )
40+
: ObjectSetSampler< Point< dimension > >{}, domain_( domain )
4041
{
41-
auto volume = box_.n_volume();
42+
auto volume = domain_.extended_n_volume();
4243
OPENGEODE_EXCEPTION( volume != 0.,
43-
"[PointSetSampler] - Undefined Bounding Box (volume ==0)." );
44+
"[PointSetSampler] - Undefined Extended Bounding "
45+
"Box (volume ==0)." );
4446
this->log_pdf_ = -std::log( volume );
47+
step_move_ = define_step_for_move();
48+
OPENGEODE_EXCEPTION( step_move_ > 0.,
49+
"[PointSetSampler] - Undefined step length for move (value == ",
50+
step_move_, ")." );
4551
}
4652

4753
Point< dimension > sample( RandomEngine& engine ) const override
4854
{
49-
return PointUniformSampler::sample< dimension >( engine, box_ );
55+
return PointUniformSampler::sample< dimension >(
56+
engine, domain_.extended_box() );
5057
}
5158

5259
Point< dimension > change(
5360
const Point< dimension >& obj, RandomEngine& engine ) const override
5461
{
55-
double ratio = 0.1;
56-
geode::Sphere< dimension > ball{ obj,
57-
ratio * std::get< 1 >( box_.smallest_length() ) };
62+
geode::Sphere< dimension > ball{ obj, step_move_ };
5863

5964
auto new_point =
6065
PointUniformSampler::sample< dimension >( engine, ball );
6166
constexpr index_t max_try{ 100 };
6267
for( const auto try_id : geode::Range{ max_try } )
6368
{
64-
if( box_.contains( new_point ) )
69+
if( domain_.extended_contains( new_point ) )
6570
{
6671
return new_point;
6772
}
6873
new_point =
6974
PointUniformSampler::sample< dimension >( engine, ball );
7075
}
71-
throw OpenGeodeException( absl::StrCat(
72-
"[PointSampler] - Cannot find a point in the box: ",
73-
box_.string() ) );
76+
throw OpenGeodeException(
77+
absl::StrCat( "[PointSampler] - Cannot find a point in the "
78+
"extended domain" ) );
7479
return obj;
7580
}
7681

7782
private:
83+
double define_step_for_move()
84+
{
85+
double ratio = 0.1;
86+
return ratio * domain_.smallest_length();
87+
}
88+
7889
bool is_valid_object( const Point< dimension >& obj ) const override
7990
{
80-
return box_.contains( obj );
91+
return domain_.extended_contains( obj );
8192
}
8293

8394
private:
84-
BoundingBox< dimension > box_;
95+
const SpatialDomain< dimension >& domain_;
96+
double step_move_{ 0. };
8597
};
8698

8799
} // namespace geode

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,32 @@
2929
#include <geode/stochastic/sampling/direct/object_set_sampler/object_set_sampler.hpp>
3030
#include <geode/stochastic/sampling/direct/point_uniform_sampler.hpp>
3131
#include <geode/stochastic/sampling/direct/segment_uniform_sampler.hpp>
32+
#include <geode/stochastic/spatial/spatial_domain.hpp>
3233

3334
namespace geode
3435
{
3536
class UniformSegmentSetSampler : public ObjectSetSampler< OwnerSegment2D >
3637
{
3738
public:
38-
UniformSegmentSetSampler( const BoundingBox< 2 >& box,
39+
UniformSegmentSetSampler( const SpatialDomain< 2 >& domain,
3940
const DoubleSampler::Distribution& length,
4041
const DoubleSampler::Distribution& azimuth )
4142
: ObjectSetSampler< OwnerSegment2D >{},
42-
box_{ box },
43+
domain_{ domain },
4344
length_{ length },
4445
azimuth_{ azimuth }
4546
{
46-
auto volume = box_.n_volume();
47+
auto volume = domain_.extended_n_volume();
4748
OPENGEODE_EXCEPTION( volume != 0.,
48-
"[SegmentSetSampler] - Undefined Bounding Box (volume == 0)." );
49+
"[SegmentSetSampler] - Undefined Extended Bounding "
50+
"Box (volume ==0)." );
4951
this->log_pdf_ = -std::log( volume );
5052
}
5153

5254
OwnerSegment2D sample( RandomEngine& engine ) const override
5355
{
5456
auto seg = SegmentUniformSampler::sample(
55-
engine, box_, length_, azimuth_ );
57+
engine, domain_.extended_box(), length_, azimuth_ );
5658
return seg;
5759
}
5860

@@ -72,8 +74,8 @@ namespace geode
7274
constexpr index_t max_try{ 100 };
7375
for( const auto try_id : geode::Range{ max_try } )
7476
{
75-
if( box_.contains( new_point )
76-
|| box_.contains( extremities[other] ) )
77+
if( domain_.extended_contains( new_point )
78+
|| domain_.extended_contains( extremities[other] ) )
7779
{
7880
OwnerSegment2D new_segment{ obj };
7981
new_segment.set_point( current, new_point );
@@ -82,22 +84,20 @@ namespace geode
8284
new_point = PointUniformSampler::sample< 2 >( engine, ball );
8385
}
8486
throw OpenGeodeException( absl::StrCat(
85-
"[PointSampler] - Cannot find a point in the box: ",
86-
box_.string() ) );
87+
"[SegmentSetSampler] - Cannot find a point in the box" ) );
8788
return obj;
8889
}
8990

9091
private:
9192
bool is_valid_object( const OwnerSegment2D& obj ) const override
9293
{
9394
const auto& extremities = obj.vertices();
94-
95-
return box_.contains( extremities[0] )
96-
|| box_.contains( extremities[1] );
95+
return domain_.extended_contains( extremities[0] )
96+
|| domain_.extended_contains( extremities[1] );
9797
}
9898

9999
private:
100-
BoundingBox2D box_;
100+
const SpatialDomain< 2 >& domain_;
101101
DoubleSampler::Distribution length_;
102102
DoubleSampler::Distribution azimuth_;
103103
};

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <geode/stochastic/sampling/mcmc/models/components/pairwise_term.hpp>
3333
#include <geode/stochastic/sampling/mcmc/proposal/classical_proposals.hpp>
3434
#include <geode/stochastic/spatial/pairwise_interactions.hpp>
35+
#include <geode/stochastic/spatial/spatial_domain.hpp>
3536

3637
namespace geode
3738
{
@@ -72,7 +73,10 @@ namespace geode
7273
class FractureSimulationRunner : public SimulationRunner< OwnerSegment2D >
7374
{
7475
public:
75-
FractureSimulationRunner( const BoundingBox2D& box ) : box_( box ) {}
76+
FractureSimulationRunner( const SpatialDomain< 2 >& domain )
77+
: SimulationRunner< OwnerSegment2D >( domain )
78+
{
79+
}
7680

7781
void add_fracture_set_descriptor(
7882
const FractureSetDescription& descriptor )
@@ -101,7 +105,7 @@ namespace geode
101105
set_desc.azimuth );
102106
this->set_samplers_.push_back(
103107
std::make_unique< UniformSegmentSetSampler >(
104-
box_, length_distribution, azimuth_distribution ) );
108+
domain_, length_distribution, azimuth_distribution ) );
105109

106110
add_birth_death_change_moves( this->set_samplers_.back(),
107111
*proposal_kernel, set_id, set_desc.birth_ratio,
@@ -159,7 +163,6 @@ namespace geode
159163
}
160164

161165
private:
162-
BoundingBox2D box_;
163166
std::vector< FractureSetDescription > set_descriptors_;
164167
};
165168

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <geode/stochastic/sampling/mcmc/helpers/simulation_printer.hpp>
2828
#include <geode/stochastic/sampling/mcmc/metropolis_hasting_sampler.hpp>
2929
#include <geode/stochastic/sampling/mcmc/models/energy_term_collection.hpp>
30+
#include <geode/stochastic/spatial/spatial_domain.hpp>
3031

3132
#include <absl/strings/str_join.h>
3233

@@ -62,7 +63,8 @@ namespace geode
6263
class SimulationRunner
6364
{
6465
public:
65-
SimulationRunner() = default;
66+
SimulationRunner( const SpatialDomain< ObjectType::dim >& domain )
67+
: domain_( domain ){};
6668
virtual ~SimulationRunner() = default;
6769

6870
virtual void initialize() = 0;
@@ -153,6 +155,7 @@ namespace geode
153155
}
154156

155157
protected:
158+
SpatialDomain< ObjectType::dim > domain_;
156159
std::vector< std::unique_ptr< geode::ObjectSetSampler< ObjectType > > >
157160
set_samplers_;
158161

src/geode/stochastic/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ add_geode_library(
4040
"spatial/object_neighborhood.hpp"
4141
"spatial/object_helpers.hpp"
4242
"spatial/pairwise_interactions.hpp"
43+
"spatial/spatial_domain.hpp"
4344
"spatial/details/RTree.hpp"
4445
"sampling/direct/object_set_sampler/object_set_sampler.hpp"
4546
"sampling/direct/object_set_sampler/point_set_sampler.hpp"

tests/stochastic/sampling/mcmc/proposal/test-proposal-kernel.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ namespace
5656
geode::BoundingBox2D box;
5757
box.add_point( min_point );
5858
box.add_point( max_point );
59+
geode::SpatialDomain domain( box, 0. );
5960

60-
geode::UniformPointSetSampler< 2 > sampler( box );
61+
geode::UniformPointSetSampler< 2 > sampler( domain );
6162

6263
// Create classical birth-death-change kernel
6364
auto kernel = geode::create_birth_death_change_kernel< geode::Point2D >(

tests/stochastic/sampling/mcmc/test-metropolis-hasting-sampler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,11 @@ int main()
159159
geode::BoundingBox2D box;
160160
box.add_point( min_point );
161161
box.add_point( max_point );
162+
geode::SpatialDomain domain( box, 0. );
162163

163164
geode::ObjectSets< geode::Point2D > state;
164165
const auto set_id = state.add_set( "default_name" );
165-
geode::UniformPointSetSampler< 2 > sampler( box );
166+
geode::UniformPointSetSampler< 2 > sampler( domain );
166167

167168
double birth_prob = 0.3;
168169
double death_prob = 0.1;

tests/stochastic/sampling/mcmc/test-mh-fractures.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ namespace
3636
geode::BoundingBox2D box;
3737
box.add_point( geode::Point2D{ { 0.0, 0.0 } } );
3838
box.add_point( geode::Point2D{ { 100.0, 100.0 } } );
39-
39+
// todo change
40+
geode::SpatialDomain domain( box, 0. );
4041
// --- Object set
4142
geode::FractureSetDescription setA;
4243
setA.name = "A";
@@ -57,7 +58,7 @@ namespace
5758
setA.p20 = 0.05;
5859
setA.minimal_spacing = 1.;
5960

60-
geode::FractureSimulationRunner runner( box );
61+
geode::FractureSimulationRunner runner( domain );
6162
runner.add_fracture_set_descriptor( setA );
6263

6364
runner.initialize();
@@ -90,6 +91,8 @@ namespace
9091
geode::BoundingBox2D box;
9192
box.add_point( geode::Point2D{ { 0.0, 0.0 } } );
9293
box.add_point( geode::Point2D{ { 100.0, 100.0 } } );
94+
// todo change
95+
geode::SpatialDomain domain( box, 0. );
9396

9497
// --- Object set
9598
geode::FractureSetDescription setA;
@@ -133,7 +136,7 @@ namespace
133136
setB.p20 = 0.05;
134137
setB.minimal_spacing = 2.;
135138

136-
geode::FractureSimulationRunner runner( box );
139+
geode::FractureSimulationRunner runner( domain );
137140
runner.add_fracture_set_descriptor( setA );
138141
runner.add_fracture_set_descriptor( setB );
139142

tests/stochastic/sampling/mcmc/test-mh-poisson.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ namespace
4949
: public geode::SimulationRunner< geode::Point2D >
5050
{
5151
public:
52-
PoissonSimulationRunner( const geode::BoundingBox2D& box )
53-
: box_( box ) {};
52+
PoissonSimulationRunner( const geode::SpatialDomain< 2 >& domain )
53+
: geode::SimulationRunner< geode::Point2D >( domain ){};
5454

5555
void add_set_descriptor( const SetDescription& descriptor )
5656
{
@@ -79,7 +79,7 @@ namespace
7979

8080
this->set_samplers_.push_back(
8181
std::make_unique< geode::UniformPointSetSampler< 2 > >(
82-
box_ ) );
82+
domain_ ) );
8383

8484
geode::add_birth_death_change_moves( this->set_samplers_.back(),
8585
*proposal_kernel, set_id, set_desc.birth_ratio,
@@ -163,6 +163,7 @@ namespace
163163
geode::BoundingBox2D box;
164164
box.add_point( geode::Point2D{ { 0.0, 0.0 } } );
165165
box.add_point( geode::Point2D{ { 10.0, 10.0 } } );
166+
geode::SpatialDomain domain( box, 0. );
166167

167168
std::array< double, 4 > birth_ratio{ 0.1, 0.5, 2., 4. };
168169
std::array< double, 4 > change_ratio{ 0., 1., 1., 0. };
@@ -182,7 +183,7 @@ namespace
182183
densityA.density = 0.3;
183184
densityA.target_count = 30.0;
184185

185-
PoissonSimulationRunner runner( box );
186+
PoissonSimulationRunner runner( domain );
186187
runner.add_set_descriptor( setA );
187188
runner.add_density_descriptor( densityA );
188189
runner.initialize();
@@ -216,6 +217,7 @@ namespace
216217
geode::BoundingBox2D box;
217218
box.add_point( geode::Point2D{ { 0.0, 0.0 } } );
218219
box.add_point( geode::Point2D{ { 10.0, 10.0 } } );
220+
geode::SpatialDomain domain( box, 0. );
219221

220222
// --- Set descriptions
221223
SetDescription set01{ "set01", 2.0, 3.0, 1.0 };
@@ -227,7 +229,7 @@ namespace
227229
PoissonDensityDescription density02{ "set02", 0.4, 40.0 };
228230
PoissonDensityDescription density03{ "set03", 0.3, 30.0 };
229231

230-
PoissonSimulationRunner runner( box );
232+
PoissonSimulationRunner runner( domain );
231233
runner.add_set_descriptor( set01 );
232234
runner.add_set_descriptor( set02 );
233235
runner.add_set_descriptor( set03 );

0 commit comments

Comments
 (0)