Skip to content

Commit dc8f53d

Browse files
feat(Helpers): Fracture Simulation Helpers
1 parent 2cd0a74 commit dc8f53d

15 files changed

Lines changed: 515 additions & 215 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ namespace geode
8181
}
8282

8383
private:
84-
const BoundingBox< dimension >& box_;
84+
BoundingBox< dimension > box_;
8585
};
8686

8787
} // namespace geode
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright (c) 2019 - 2025 Geode-solutions
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*
22+
*/
23+
24+
#pragma once
25+
26+
#include <geode/geometry/basic_objects/segment.hpp>
27+
#include <geode/geometry/basic_objects/sphere.hpp>
28+
29+
#include <geode/stochastic/sampling/direct/object_set_sampler/object_set_sampler.hpp>
30+
#include <geode/stochastic/sampling/direct/point_uniform_sampler.hpp>
31+
#include <geode/stochastic/sampling/direct/segment_uniform_sampler.hpp>
32+
33+
namespace geode
34+
{
35+
class UniformSegmentSetSampler : public ObjectSetSampler< OwnerSegment2D >
36+
{
37+
public:
38+
UniformSegmentSetSampler( const BoundingBox< 2 >& box,
39+
const DoubleSampler::Distribution& length,
40+
const DoubleSampler::Distribution& azimuth )
41+
: ObjectSetSampler< OwnerSegment2D >{},
42+
box_{ box },
43+
length_{ length },
44+
azimuth_{ azimuth }
45+
{
46+
auto volume = box_.n_volume();
47+
OPENGEODE_EXCEPTION( volume != 0.,
48+
"[SegmentSetSampler] - Undefined Bounding Box (volume == 0)." );
49+
this->log_pdf_ = -std::log( volume );
50+
}
51+
52+
OwnerSegment2D sample( RandomEngine& engine ) const override
53+
{
54+
auto seg = SegmentUniformSampler::sample(
55+
engine, box_, length_, azimuth_ );
56+
return seg;
57+
}
58+
59+
OwnerSegment2D change(
60+
const OwnerSegment2D& obj, RandomEngine& engine ) const override
61+
{
62+
double ratio = 0.1;
63+
const auto& extremities = obj.vertices();
64+
const auto current =
65+
static_cast< local_index_t >( engine.sample_bernoulli( 0.5 ) );
66+
67+
geode::Sphere< 2 > ball{ extremities[current],
68+
ratio * obj.length() };
69+
70+
auto new_point = PointUniformSampler::sample< 2 >( engine, ball );
71+
constexpr index_t max_try{ 100 };
72+
for( const auto try_id : geode::Range{ max_try } )
73+
{
74+
if( box_.contains( new_point ) )
75+
{
76+
OwnerSegment2D new_segment{ obj };
77+
new_segment.set_point( current, new_point );
78+
return new_segment;
79+
}
80+
new_point = PointUniformSampler::sample< 2 >( engine, ball );
81+
}
82+
throw OpenGeodeException( absl::StrCat(
83+
"[PointSampler] - Cannot find a point in the box: ",
84+
box_.string() ) );
85+
return obj;
86+
}
87+
88+
private:
89+
bool is_valid_object( const OwnerSegment2D& obj ) const override
90+
{
91+
const auto& extremities = obj.vertices();
92+
93+
return box_.contains( extremities[0] )
94+
&& box_.contains( extremities[1] );
95+
}
96+
97+
private:
98+
BoundingBox2D box_;
99+
DoubleSampler::Distribution length_;
100+
DoubleSampler::Distribution azimuth_;
101+
};
102+
103+
} // namespace geode

include/geode/stochastic/sampling/mcmc/metropolis_hasting_sampler.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,6 @@ namespace geode
219219
const auto old_object_id = proposal.old_object_id();
220220
const auto delta_log_energy = gibbs_energy_.delta_log_change(
221221
state, old_object_id, new_object );
222-
// should we test that objects are in the same group?
223-
// should be ensured by the dynamic
224222
return accept_or_reject( proposal, state, engine, delta_log_energy,
225223
[]( auto& state, auto& proposal ) {
226224
state.update_object( proposal.old_object_id(),

include/geode/stochastic/spatial/pairwise_interactions.hpp

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include <geode/basic/uuid.hpp>
2727

28+
#include <geode/geometry/basic_objects/segment.hpp>
2829
#include <geode/geometry/distance.hpp>
2930
#include <geode/geometry/point.hpp>
3031

@@ -74,38 +75,26 @@ namespace geode
7475
SCOPE scope_{ SCOPE::all_set };
7576
};
7677

78+
/*!
79+
* EuclideanCutoffInteraction
80+
* A pairwise interaction that returns 1 if the Euclidean distance
81+
* between objects is within a cutoff radius, otherwise 0.
82+
*/
7783
template < typename Type >
7884
class EuclideanCutoffInteraction : public PairwiseInteraction< Type >
7985
{
8086
public:
81-
EuclideanCutoffInteraction( double cutoff_distance )
82-
: PairwiseInteraction< Type >(), cutoff_distance_( cutoff_distance )
83-
{
84-
}
87+
explicit EuclideanCutoffInteraction( double cutoff_distance );
8588
EuclideanCutoffInteraction( double cutoff_distance,
86-
typename PairwiseInteraction< Type >::SCOPE scope )
87-
: PairwiseInteraction< Type >( scope ),
88-
cutoff_distance_( cutoff_distance )
89-
{
90-
}
89+
typename PairwiseInteraction< Type >::SCOPE scope );
9190

92-
double neighborhood_searching_distance() const override
93-
{
94-
return cutoff_distance_;
95-
}
91+
double neighborhood_searching_distance() const override;
9692

9793
protected:
9894
double compute( const ObjectRef< Type >& object_a,
99-
const ObjectRef< Type >& object_b ) const override
100-
{
101-
auto dist = geode::point_point_distance(
102-
object_barycenter( object_a.object ),
103-
object_barycenter( object_b.object ) );
104-
return dist <= cutoff_distance_ ? 1.0 : 0.0;
105-
}
95+
const ObjectRef< Type >& object_b ) const override;
10696

10797
private:
10898
double cutoff_distance_{ GLOBAL_EPSILON };
10999
};
110-
111100
} // namespace geode

src/geode/stochastic/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ add_geode_library(
2525
"spatial/object_set.cpp"
2626
"spatial/object_sets.cpp"
2727
"spatial/object_neighborhood.cpp"
28+
"spatial/pairwise_interactions.cpp"
2829
"sampling/direct/ball_sampler.cpp"
2930
"sampling/direct/bounding_box_sampler.cpp"
3031
"sampling/direct/double_sampler.cpp"
@@ -43,6 +44,7 @@ add_geode_library(
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"
47+
"sampling/direct/object_set_sampler/segment_set_sampler.hpp"
4648
"sampling/direct/ball_sampler.hpp"
4749
"sampling/direct/bounding_box_sampler.hpp"
4850
"sampling/direct/double_sampler.hpp"

src/geode/stochastic/spatial/object_set.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ namespace geode
8787
template < typename Type >
8888
std::string ObjectSet< Type >::string() const
8989
{
90-
return absl::StrCat(
91-
"ObjectSet ", this->id().string(), " with ", size(), " objects" );
90+
return absl::StrCat( "ObjectSet ", this->name(), " (",
91+
this->id().string(), ") contains ", size(), " objects" );
9292
}
9393

9494
// Explicit template instantiation

src/geode/stochastic/spatial/object_sets.cpp

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,7 @@
44

55
#include <geode/geometry/basic_objects/segment.hpp>
66
#include <geode/geometry/point.hpp>
7-
namespace
8-
{
9-
template < geode::index_t dimension >
10-
geode::Vector< dimension > enlarge_vector( double distance );
11-
12-
template <>
13-
geode::Vector2D enlarge_vector< 2 >( double distance )
14-
{
15-
return geode::Vector2D{ { distance, distance } };
16-
}
177

18-
template <>
19-
geode::Vector3D enlarge_vector< 3 >( double distance )
20-
{
21-
return geode::Vector3D{ { distance, distance, distance } };
22-
}
23-
template < geode::index_t dimension >
24-
void enlarge_box(
25-
geode::BoundingBox< dimension >& box, double search_distance )
26-
{
27-
auto vec = enlarge_vector< dimension >( search_distance );
28-
box.add_point( box.min() - vec );
29-
box.add_point( box.max() + vec );
30-
}
31-
} // namespace
328
namespace geode
339
{
3410
template < typename Type >
@@ -150,7 +126,7 @@ namespace geode
150126
const ObjectId& object_id, double searching_distance ) const
151127
{
152128
auto box = object_bounding_box( get_object( object_id ) );
153-
enlarge_box< Type::dim >( box, searching_distance );
129+
box.extends( searching_distance * 2. );
154130
return neighborhood_.get_all_neighbor_ids( box, object_id );
155131
}
156132

@@ -159,7 +135,7 @@ namespace geode
159135
const Type& object, double searching_distance ) const
160136
{
161137
auto box = object_bounding_box( object );
162-
enlarge_box< Type::dim >( box, searching_distance );
138+
box.extends( searching_distance * 2. );
163139
return neighborhood_.get_all_neighbor_ids( box, std::nullopt );
164140
}
165141

@@ -173,12 +149,11 @@ namespace geode
173149
template < typename Type >
174150
std::string ObjectSets< Type >::string() const
175151
{
176-
auto message =
177-
absl::StrCat( "ObjectSets with ", nb_sets(), " ObjectSet:" );
152+
auto message = absl::StrCat( "ObjectSets with ", nb_objects(),
153+
" objects in, ", nb_sets(), " sets" );
178154
for( const auto& [set_id, objs] : sets_ )
179155
{
180-
absl::StrAppend( &message, "\n\t - set uuid: ", set_id.string(),
181-
"--> ", objs.string() );
156+
absl::StrAppend( &message, "\n\t --> ", objs.string() );
182157
}
183158
return message;
184159
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (c) 2019 - 2025 Geode-solutions
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*
22+
*/
23+
24+
#include <geode/stochastic/spatial/pairwise_interactions.hpp>
25+
26+
#include <geode/geometry/basic_objects/segment.hpp>
27+
#include <geode/geometry/distance.hpp>
28+
29+
namespace
30+
{
31+
template < geode::index_t dimension >
32+
double compute_euclidean_distance( const geode::Point< dimension >& point1,
33+
const geode::Point< dimension >& point2 )
34+
{
35+
return geode::point_point_distance( point1, point2 );
36+
}
37+
template < geode::index_t dimension >
38+
double compute_euclidean_distance( const geode::Segment< dimension >& seg1,
39+
const geode::Segment< dimension >& seg2 )
40+
{
41+
return std::get< 0 >( geode::segment_segment_distance( seg1, seg2 ) );
42+
}
43+
} // namespace
44+
namespace geode
45+
{
46+
template < typename Type >
47+
EuclideanCutoffInteraction< Type >::EuclideanCutoffInteraction(
48+
double cutoff_distance )
49+
: PairwiseInteraction< Type >(), cutoff_distance_( cutoff_distance )
50+
{
51+
}
52+
53+
template < typename Type >
54+
EuclideanCutoffInteraction< Type >::EuclideanCutoffInteraction(
55+
double cutoff_distance,
56+
typename PairwiseInteraction< Type >::SCOPE scope )
57+
: PairwiseInteraction< Type >( scope ),
58+
cutoff_distance_( cutoff_distance )
59+
{
60+
}
61+
62+
template < typename Type >
63+
double EuclideanCutoffInteraction< Type >::neighborhood_searching_distance()
64+
const
65+
{
66+
return cutoff_distance_;
67+
}
68+
69+
template < typename Type >
70+
double EuclideanCutoffInteraction< Type >::compute(
71+
const ObjectRef< Type >& object_a,
72+
const ObjectRef< Type >& object_b ) const
73+
{
74+
auto dist = compute_euclidean_distance< Type::dim >(
75+
object_a.object, object_b.object );
76+
return dist <= cutoff_distance_ ? 1.0 : 0.0;
77+
}
78+
79+
template class opengeode_stochastic_stochastic_api
80+
EuclideanCutoffInteraction< Point< 2 > >;
81+
template class opengeode_stochastic_stochastic_api
82+
EuclideanCutoffInteraction< Point< 3 > >;
83+
84+
template class opengeode_stochastic_stochastic_api
85+
EuclideanCutoffInteraction< OwnerSegment< 2 > >;
86+
} // namespace geode

tests/stochastic/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ add_geode_test(
121121
${PROJECT_NAME}::stochastic
122122
)
123123

124+
add_geode_test(
125+
SOURCE "sampling/mcmc/test-mh-fractures.cpp"
126+
DEPENDENCIES
127+
OpenGeode::basic
128+
OpenGeode::geometry
129+
${PROJECT_NAME}::stochastic
130+
)
131+
124132
add_geode_test(
125133
SOURCE "sampling/mcmc/test-mh-poisson.cpp"
126134
DEPENDENCIES

tests/stochastic/sampling/direct/test-double-sampler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void test_double_sampler( geode::RandomEngine& engine )
5151

5252
geode::TruncatedGaussian t_gaussian_double;
5353
t_gaussian_double.mean = 0.;
54-
t_gaussian_double.mean = 1.;
54+
t_gaussian_double.standard_deviation = 1.;
5555
t_gaussian_double.max_value = 1.;
5656
t_gaussian_double.min_value = -1.;
5757
value = 1000.;

0 commit comments

Comments
 (0)