Skip to content

Commit 8986c26

Browse files
authored
Merge pull request #30 from Geode-solutions/contrain_p21
feat(FractureModel): add p21 controle
2 parents 74791f7 + ab52b57 commit 8986c26

12 files changed

Lines changed: 495 additions & 178 deletions

File tree

bindings/python/src/stochastic/sampling/mcmc/helpers/fracture_simulation_runner.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ namespace geode
3636
.def_readwrite( "length", &FractureSetDescription::length )
3737
.def_readwrite( "azimuth", &FractureSetDescription::azimuth )
3838
.def_readwrite( "p20", &FractureSetDescription::p20 )
39+
.def_readwrite( "p21", &FractureSetDescription::p21 )
3940
.def( "add_observed_fracture",
4041
[]( FractureSetDescription& self, const geode::Point2D& a,
4142
const geode::Point2D& b ) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def test_fracture_simulator():
6060

6161
# positioning
6262
setA.p20 = 0.06
63+
setA.p21 = 10
6364
setA.minimal_spacing = 1.0
6465

6566
runner = stochastic.FractureSimulationRunner(domain)

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

Lines changed: 81 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <geode/stochastic/sampling/direct/object_set_sampler/segment_set_sampler.hpp>
3030
#include <geode/stochastic/sampling/mcmc/helpers/simulation_runner.hpp>
3131
#include <geode/stochastic/sampling/mcmc/models/components/density_term.hpp>
32+
#include <geode/stochastic/sampling/mcmc/models/components/intensity_term.hpp>
3233
#include <geode/stochastic/sampling/mcmc/models/components/pairwise_term.hpp>
3334
#include <geode/stochastic/sampling/mcmc/proposal/classical_proposals.hpp>
3435
#include <geode/stochastic/spatial/pairwise_interactions.hpp>
@@ -48,7 +49,7 @@ namespace geode
4849
// positionning
4950
double p20;
5051
std::vector< std::array< geode::Point2D, 2 > > observed_fractures;
51-
// double p21;
52+
double p21{ 1. };
5253
double minimal_spacing{ 0. };
5354

5455
// mh dynamique
@@ -107,7 +108,8 @@ namespace geode
107108
std::make_unique< ProposalKernel< OwnerSegment2D > >();
108109

109110
// Mapping set names -> UUID
110-
std::unordered_map< std::string, uuid > name_to_uuid;
111+
// std::unordered_map< std::string, uuid >
112+
// set_name_to_uuid_;
111113

112114
// Step 1: create object sets and samplers
113115
for( const auto& set_desc : set_descriptors_ )
@@ -120,7 +122,7 @@ namespace geode
120122
fixed_object[0], fixed_object[1] },
121123
set_id, true );
122124
}
123-
name_to_uuid[set_desc.name] = set_id;
125+
set_name_to_uuid_[set_desc.name] = set_id;
124126

125127
auto length_distribution =
126128
DoubleSampler::create_distribution( set_desc.length );
@@ -139,52 +141,12 @@ namespace geode
139141
// Step 2: create density energy terms
140142
for( const auto& set_desc : set_descriptors_ )
141143
{
142-
const auto set_id = name_to_uuid.at( set_desc.name );
143-
// p20
144-
this->ordered_energy_terms_.push_back(
145-
this->energy_terms_collection_.add_energy_term(
146-
std::make_unique< DensityTerm< OwnerSegment2D > >(
147-
absl::StrCat( set_desc.name, "_density" ),
148-
set_desc.p20, std::vector< uuid >{ set_id },
149-
this->domain_ ) ) );
150-
// spacing
151-
if( set_desc.minimal_spacing > GLOBAL_EPSILON )
152-
{
153-
auto interaction = std::make_unique<
154-
EuclideanCutoffInteraction< OwnerSegment2D > >(
155-
set_desc.minimal_spacing,
156-
PairwiseInteraction<
157-
OwnerSegment2D >::SCOPE::same_set );
158-
159-
this->ordered_energy_terms_.push_back(
160-
this->energy_terms_collection_.add_energy_term(
161-
std::make_unique< PairwiseTerm< OwnerSegment2D > >(
162-
absl::StrCat( set_desc.name, "_min_spacing" ),
163-
0., std::vector< uuid >{ set_id },
164-
std::move( interaction ), this->domain_ ) ) );
165-
}
144+
set_density_term( set_desc );
145+
set_intensity_term( set_desc );
146+
set_minimal_spacing_term( set_desc );
166147
}
167-
// x node monitoring
168-
if( std::fabs( beta_x_node_ - 1. ) > GLOBAL_EPSILON )
169-
{
170-
std::vector< uuid > set_uuids;
171-
set_uuids.reserve( name_to_uuid.size() );
172-
for( const auto& [name, id] : name_to_uuid )
173-
{
174-
set_uuids.push_back( id );
175-
}
176-
auto interaction = std::make_unique<
177-
EuclideanCutoffInteraction< OwnerSegment2D > >(
178-
0., PairwiseInteraction<
179-
OwnerSegment2D >::SCOPE::different_set );
148+
set_x_intersection_term();
180149

181-
this->ordered_energy_terms_.push_back(
182-
this->energy_terms_collection_.add_energy_term(
183-
std::make_unique< PairwiseTerm< OwnerSegment2D > >(
184-
absl::StrCat( "inter_set_x_nodes" ), beta_x_node_,
185-
set_uuids, std::move( interaction ),
186-
this->domain_ ) ) );
187-
}
188150
this->mh_sampler_ =
189151
std::make_unique< MetropolisHastings< OwnerSegment2D > >(
190152
this->energy_terms_collection_,
@@ -229,8 +191,80 @@ namespace geode
229191
return message;
230192
}
231193

194+
private:
195+
void set_density_term( const FractureSetDescription& set_desc )
196+
{
197+
const auto set_id = set_name_to_uuid_.at( set_desc.name );
198+
this->ordered_energy_terms_.push_back(
199+
this->energy_terms_collection_.add_energy_term(
200+
std::make_unique< DensityTerm< OwnerSegment2D > >(
201+
absl::StrCat( set_desc.name, "_density" ), set_desc.p20,
202+
std::vector< uuid >{ set_id }, this->domain_ ) ) );
203+
}
204+
205+
void set_intensity_term( const FractureSetDescription& set_desc )
206+
{
207+
if( std::fabs( set_desc.p21 - 1. ) < GLOBAL_EPSILON )
208+
{
209+
return;
210+
}
211+
const auto set_id = set_name_to_uuid_.at( set_desc.name );
212+
this->ordered_energy_terms_.push_back(
213+
this->energy_terms_collection_.add_energy_term(
214+
std::make_unique< IntensityTerm >(
215+
absl::StrCat( set_desc.name, "_intensity" ),
216+
set_desc.p21, std::vector< uuid >{ set_id },
217+
0.5 * this->domain_.smallest_length(),
218+
this->domain_ ) ) );
219+
}
220+
221+
void set_minimal_spacing_term( const FractureSetDescription& set_desc )
222+
{
223+
if( set_desc.minimal_spacing < GLOBAL_EPSILON )
224+
{
225+
return;
226+
}
227+
const auto set_id = set_name_to_uuid_.at( set_desc.name );
228+
auto interaction = std::make_unique<
229+
EuclideanCutoffInteraction< OwnerSegment2D > >(
230+
set_desc.minimal_spacing,
231+
PairwiseInteraction< OwnerSegment2D >::SCOPE::same_set );
232+
233+
this->ordered_energy_terms_.push_back(
234+
this->energy_terms_collection_.add_energy_term(
235+
std::make_unique< PairwiseTerm< OwnerSegment2D > >(
236+
absl::StrCat( set_desc.name, "_min_spacing" ), 0.,
237+
std::vector< uuid >{ set_id }, std::move( interaction ),
238+
this->domain_ ) ) );
239+
}
240+
241+
void set_x_intersection_term()
242+
{
243+
if( std::fabs( beta_x_node_ - 1. ) > GLOBAL_EPSILON )
244+
{
245+
std::vector< uuid > set_uuids;
246+
set_uuids.reserve( set_name_to_uuid_.size() );
247+
for( const auto& [name, id] : set_name_to_uuid_ )
248+
{
249+
set_uuids.push_back( id );
250+
}
251+
auto interaction = std::make_unique<
252+
EuclideanCutoffInteraction< OwnerSegment2D > >(
253+
0., PairwiseInteraction<
254+
OwnerSegment2D >::SCOPE::different_set );
255+
256+
this->ordered_energy_terms_.push_back(
257+
this->energy_terms_collection_.add_energy_term(
258+
std::make_unique< PairwiseTerm< OwnerSegment2D > >(
259+
absl::StrCat( "inter_set_x_nodes" ), beta_x_node_,
260+
set_uuids, std::move( interaction ),
261+
this->domain_ ) ) );
262+
}
263+
}
264+
232265
private:
233266
std::vector< FractureSetDescription > set_descriptors_;
267+
std::unordered_map< std::string, uuid > set_name_to_uuid_;
234268
// x node monitoring
235269
double beta_x_node_{ 1. };
236270
};

include/geode/stochastic/sampling/mcmc/models/components/density_term.hpp

Lines changed: 22 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -24,79 +24,39 @@
2424

2525
#include <geode/stochastic/spatial/object_sets.hpp>
2626

27-
#include <geode/stochastic/sampling/mcmc/models/components/energy_term.hpp>
27+
#include <geode/stochastic/sampling/mcmc/models/components/single_object_term.hpp>
2828

2929
namespace geode
3030
{
31-
/// ObjectCountTerm
3231
template < typename ObjectType >
33-
class DensityTerm : public EnergyTerm< ObjectType >
32+
class DensityTerm : public SingleObjectTerm< ObjectType,
33+
std::function< double( const ObjectType&,
34+
const SpatialDomain< ObjectType::dim >& ) > >
3435
{
3536
public:
3637
explicit DensityTerm( std::string_view name,
3738
double lambda,
3839
std::vector< uuid > targeted_set_ids,
3940
const SpatialDomain< ObjectType::dim >& domain )
40-
: EnergyTerm< ObjectType >(
41-
name, lambda, std::move( targeted_set_ids ), domain )
41+
: SingleObjectTerm< ObjectType,
42+
std::function< double( const ObjectType&,
43+
const SpatialDomain< ObjectType::dim >& ) > >(
44+
name,
45+
lambda,
46+
std::move( targeted_set_ids ),
47+
1.0, // scale by domain area to get density per unit
48+
[]( const ObjectType& obj,
49+
const SpatialDomain< ObjectType::dim >& domain ) {
50+
if( SpatialDomainChecker<
51+
ObjectType >::is_anchored_in_domain( domain,
52+
obj ) )
53+
{
54+
return 1.0;
55+
}
56+
return 0.0;
57+
}, // contribution = 1 anchoredin domain
58+
domain )
4259
{
4360
}
44-
45-
double total_log( const ObjectSets< ObjectType >& state ) const override
46-
{
47-
const auto n = this->statistic( state );
48-
return this->contribution( n );
49-
}
50-
51-
double delta_log_add( const ObjectSets< ObjectType >& /*state*/,
52-
const ObjectRef< ObjectType >& new_object ) const override
53-
{
54-
if( !this->is_targeted_set( new_object.set_id )
55-
|| !this->is_anchored_in_domain( new_object.object ) )
56-
{
57-
return 0.0;
58-
}
59-
return this->contribution( 1.0 );
60-
}
61-
62-
double delta_log_remove( const ObjectSets< ObjectType >& state,
63-
const ObjectId& object_id ) const override
64-
{
65-
if( !this->is_targeted_set( object_id.set_id )
66-
|| !this->is_anchored_in_domain(
67-
state.get_object( object_id ) ) )
68-
{
69-
return 0.0;
70-
}
71-
return this->contribution( -1.0 );
72-
}
73-
74-
double delta_log_change( const ObjectSets< ObjectType >& state,
75-
const ObjectId& old_object_id,
76-
const ObjectRef< ObjectType >& new_object ) const override
77-
{
78-
auto old_in = this->is_anchored_in_domain(
79-
state.get_object( old_object_id ) );
80-
auto new_in = this->is_anchored_in_domain( new_object.object );
81-
if( old_in == new_in )
82-
{
83-
return 0.0;
84-
}
85-
return this->contribution( new_in ? 1.0 : -1.0 );
86-
}
87-
88-
double statistic( const ObjectSets< ObjectType >& state ) const override
89-
{
90-
double sum = 0.0;
91-
this->for_each_targeted_object(
92-
state, [&]( const ObjectId& obj_id ) {
93-
if( this->is_anchored_in_domain(
94-
state.get_object( obj_id ) ) )
95-
{
96-
sum += 1.0;
97-
}
98-
} );
99-
return sum;
100-
}
10161
};
10262
} // namespace geode

include/geode/stochastic/sampling/mcmc/models/components/energy_term.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,17 +156,17 @@ namespace geode
156156
targeted_set_ids_.begin(), targeted_set_ids_.end(), set_id );
157157
}
158158

159-
bool is_anchored_in_domain( const ObjectType& obj ) const
159+
const SpatialDomain< ObjectType::dim >& domain() const
160160
{
161-
return SpatialDomainChecker< ObjectType >::is_anchored_in_domain(
162-
domain_, obj );
161+
return domain_;
163162
}
164163

165-
bool intersects_domain( const ObjectType& obj ) const
166-
{
167-
return SpatialDomainChecker< ObjectType >::intersects_domain(
168-
domain_, obj );
169-
}
164+
// bool intersects_domain( const ObjectType& obj ) const
165+
// {
166+
// return SpatialDomainChecker< ObjectType
167+
// >::intersects_domain(
168+
// domain_, obj );
169+
// }
170170

171171
template < typename Func >
172172
void for_each_targeted_object(
@@ -185,6 +185,6 @@ namespace geode
185185
private:
186186
detail::EnergyScale energy_scale_;
187187
std::vector< uuid > targeted_set_ids_;
188-
const SpatialDomain< ObjectType::dim > domain_;
188+
const SpatialDomain< ObjectType::dim >& domain_;
189189
};
190190
} // namespace geode

0 commit comments

Comments
 (0)