1 #ifndef VORONOTALT_UPDATEABLE_RADICAL_TESSELLATION_H_ 2 #define VORONOTALT_UPDATEABLE_RADICAL_TESSELLATION_H_ 4 #include "radical_tessellation.h" 14 std::vector<RadicalTessellation::CellContactDescriptorsSummary> cells_summaries;
15 std::vector< std::vector<RadicalTessellation::ContactDescriptorSummary> > contacts_summaries;
16 std::vector< std::vector<RadicalTessellation::ContactDescriptorSummary> > contacts_summaries_with_redundancy_in_periodic_box;
24 return (cells_summaries.empty() || contacts_summaries.empty());
46 bool init(
const std::vector<SimpleSphere>& input_spheres) noexcept
49 return init(input_spheres, time_recorder);
52 bool init(
const std::vector<SimpleSphere>& input_spheres,
TimeRecorder& time_recorder) noexcept
54 return init(input_spheres,
PeriodicBox(), time_recorder);
57 bool init(
const std::vector<SimpleSphere>& input_spheres,
const PeriodicBox& periodic_box) noexcept
60 return init(input_spheres, periodic_box, time_recorder);
63 bool init(
const std::vector<SimpleSphere>& input_spheres,
const PeriodicBox& periodic_box,
TimeRecorder& time_recorder) noexcept
65 prepare_for_possible_init_or_update(time_recorder);
67 state_.spheres_container.init(input_spheres, periodic_box, time_recorder);
69 in_sync_with_backup_=
false;
72 RadicalTessellation::construct_full_tessellation(state_.spheres_container, std::vector<int>(), std::vector<int>(),
false,
true, FLOATCONST(0.0), std::vector<Float>(), buffered_temporary_storage_.tessellation_result, result_graphics, time_recorder);
74 involvement_of_spheres_for_update_.clear();
76 init_result_from_tessellation_result();
78 return !state_.result.empty();
81 bool update(
const std::vector<SimpleSphere>& new_input_spheres) noexcept
84 return update(new_input_spheres, std::vector<UnsignedInt>(),
false, time_recorder);
87 bool update(
const std::vector<SimpleSphere>& new_input_spheres,
TimeRecorder& time_recorder) noexcept
89 return update(new_input_spheres, std::vector<UnsignedInt>(),
false, time_recorder);
92 bool update(
const std::vector<SimpleSphere>& new_input_spheres,
const std::vector<UnsignedInt>& ids_of_changed_input_spheres) noexcept
95 return update(new_input_spheres, ids_of_changed_input_spheres,
true, time_recorder);
98 bool update(
const std::vector<SimpleSphere>& new_input_spheres,
const std::vector<UnsignedInt>& ids_of_changed_input_spheres,
TimeRecorder& time_recorder) noexcept
100 return update(new_input_spheres, ids_of_changed_input_spheres,
true, time_recorder);
103 bool update(
const std::vector<SimpleSphere>& new_input_spheres,
const std::vector<UnsignedInt>& provided_ids_of_changed_input_spheres,
const bool trust_provided_ids_of_changed_input_spheres,
TimeRecorder& time_recorder) noexcept
105 prepare_for_possible_init_or_update(time_recorder);
107 if(trust_provided_ids_of_changed_input_spheres && provided_ids_of_changed_input_spheres.empty())
112 if(!state_.spheres_container.update(new_input_spheres, provided_ids_of_changed_input_spheres, trust_provided_ids_of_changed_input_spheres, state_.ids_of_changed_input_spheres, state_.ids_of_affected_input_spheres, time_recorder))
117 in_sync_with_backup_=
false;
119 if(state_.ids_of_affected_input_spheres.empty())
122 RadicalTessellation::construct_full_tessellation(state_.spheres_container, std::vector<int>(), std::vector<int>(),
false,
true, FLOATCONST(0.0), std::vector<Float>(), buffered_temporary_storage_.tessellation_result, result_graphics, time_recorder);
123 init_result_from_tessellation_result();
127 update_using_current_state(time_recorder);
133 bool update_by_setting_exclusion_mask(
const UnsignedInt id_of_targeted_input_sphere,
const bool new_exclusion_status) noexcept
136 return update_by_setting_exclusion_mask(id_of_targeted_input_sphere, new_exclusion_status, time_recorder);
139 bool update_by_setting_exclusion_mask(
const UnsignedInt id_of_targeted_input_sphere,
const bool new_exclusion_status,
TimeRecorder& time_recorder) noexcept
141 if(state_.result.empty() || id_of_targeted_input_sphere>=state_.result.contacts_summaries.size()
142 || id_of_targeted_input_sphere>=state_.spheres_container.all_exclusion_statuses().size()
143 || (new_exclusion_status ? state_.spheres_container.all_exclusion_statuses()[id_of_targeted_input_sphere]>0 : state_.spheres_container.all_exclusion_statuses()[id_of_targeted_input_sphere]<1))
148 prepare_for_possible_init_or_update(time_recorder);
150 if(new_exclusion_status)
152 if(!state_.spheres_container.update_by_setting_exclusion_status(id_of_targeted_input_sphere,
true))
157 state_.ids_of_changed_input_spheres.push_back(id_of_targeted_input_sphere);
158 state_.ids_of_affected_input_spheres.push_back(id_of_targeted_input_sphere);
160 for(UnsignedInt i=0;i<state_.result.contacts_summaries[id_of_targeted_input_sphere].size();i++)
163 if(cds.id_a!=id_of_targeted_input_sphere)
165 state_.ids_of_affected_input_spheres.push_back(cds.id_a);
167 else if(cds.id_b!=id_of_targeted_input_sphere)
169 state_.ids_of_affected_input_spheres.push_back(cds.id_b);
175 if(!state_.spheres_container.update_by_setting_exclusion_status(id_of_targeted_input_sphere,
false, state_.ids_of_changed_input_spheres, state_.ids_of_affected_input_spheres))
181 in_sync_with_backup_=
false;
183 update_using_current_state(time_recorder);
188 bool restore_from_backup() noexcept
190 if(backup_enabled_ && !in_sync_with_backup_)
192 state_.assign_to_undo_update(state_backup_);
193 in_sync_with_backup_=
true;
196 return in_sync_with_backup_;
199 bool calculate_second_order_cell_volumes(std::vector< std::vector<Float> >& all_result_volumes_for_contacts_summaries) noexcept
201 all_result_volumes_for_contacts_summaries.clear();
203 if(!backup_enabled_ || state_.result.empty())
208 const UnsignedInt N=state_.result.contacts_summaries.size();
210 std::vector< std::vector<UnsignedInt> > all_neighbor_ids(N);
211 std::vector< std::vector<Float> > all_volumes_after_masking(N);
213 for(UnsignedInt i=0;i<N;i++)
215 std::vector<UnsignedInt>& i_neighbor_ids=all_neighbor_ids[i];
218 const std::vector<RadicalTessellation::ContactDescriptorSummary>& cdss=state_.result.contacts_summaries[i];
219 i_neighbor_ids.resize(cdss.size());
220 for(UnsignedInt j=0;j<cdss.size();j++)
222 i_neighbor_ids[j]=(cdss[j].id_a!=i ? cdss[j].id_a : cdss[j].id_b);
226 std::vector<Float>& i_volumes_after_masking=all_volumes_after_masking[i];
227 i_volumes_after_masking.resize(i_neighbor_ids.size(), FLOATCONST(0.0));
229 if(update_by_setting_exclusion_mask(i,
true))
231 for(UnsignedInt j=0;j<i_neighbor_ids.size();j++)
233 i_volumes_after_masking[j]=state_.result.cells_summaries[i_neighbor_ids[j]].sas_inside_volume;
235 restore_from_backup();
239 all_result_volumes_for_contacts_summaries.resize(N);
241 for(UnsignedInt i=0;i<N;i++)
243 all_result_volumes_for_contacts_summaries[i].resize(all_neighbor_ids[i].size());
244 const Float i_volume_before_masking=state_.result.cells_summaries[i].sas_inside_volume;
245 for(UnsignedInt j=0;j<all_neighbor_ids[i].size();j++)
247 const UnsignedInt neighbor_id=all_neighbor_ids[i][j];
248 const Float neighbor_volume_before_masking=state_.result.cells_summaries[neighbor_id].sas_inside_volume;
249 const Float neighbor_volume_after_masking_i=all_volumes_after_masking[i][j];
250 Float i_volume_after_masking_neighbor=FLOATCONST(0.0);
251 for(UnsignedInt relative_i=0;relative_i<all_volumes_after_masking[neighbor_id].size() && i_volume_after_masking_neighbor<=FLOATCONST(0.0);relative_i++)
253 if(all_neighbor_ids[neighbor_id][relative_i]==i)
255 i_volume_after_masking_neighbor=all_volumes_after_masking[neighbor_id][relative_i];
258 all_result_volumes_for_contacts_summaries[i][j]=(i_volume_after_masking_neighbor+neighbor_volume_after_masking_i)-(i_volume_before_masking+neighbor_volume_before_masking);
265 bool backup_enabled()
const noexcept
267 return backup_enabled_;
270 bool in_sync_with_backup()
const noexcept
272 return in_sync_with_backup_;
275 const std::vector<SimpleSphere>& input_spheres()
const noexcept
277 return state_.spheres_container.input_spheres();
280 bool exclusion_status_of_input_sphere(
const UnsignedInt id_of_input_sphere)
const noexcept
282 return (id_of_input_sphere<state_.spheres_container.all_exclusion_statuses().size() && state_.spheres_container.all_exclusion_statuses()[id_of_input_sphere]>0);
285 const Result& result()
const noexcept
287 return state_.result;
293 for(UnsignedInt i=0;i<state_.result.contacts_summaries.size();i++)
295 for(UnsignedInt j=0;j<state_.result.contacts_summaries[i].size();j++)
300 result_summary.total_contacts_summary.add(cds);
304 for(UnsignedInt i=0;i<state_.result.cells_summaries.size();i++)
306 result_summary.total_cells_summary.add(state_.result.cells_summaries[i]);
308 return result_summary;
311 const std::vector<UnsignedInt>& last_update_ids_of_changed_input_spheres()
const noexcept
313 return state_.ids_of_changed_input_spheres;
316 const std::vector<UnsignedInt>& last_update_ids_of_affected_input_spheres()
const noexcept
318 return state_.ids_of_affected_input_spheres;
321 bool last_update_was_full_reinit()
const noexcept
323 return state_.last_update_was_full_reinit;
327 struct BufferedTemporaryStorage
331 void clear() noexcept
333 tessellation_result.clear();
337 class ConditionToRemoveContact
340 explicit ConditionToRemoveContact(
const std::vector<int>& involvement) noexcept : involvement_(involvement)
346 return (involvement_.empty() || (involvement_[cds.id_a%involvement_.size()]>0 && involvement_[cds.id_b%involvement_.size()]>0));
350 const std::vector<int>& involvement_;
357 std::vector<UnsignedInt> ids_of_changed_input_spheres;
358 std::vector<UnsignedInt> ids_of_affected_input_spheres;
359 bool last_update_was_full_reinit;
361 State() noexcept : last_update_was_full_reinit(
true)
365 void assign(
const State& obj) noexcept
367 spheres_container.assign(obj.spheres_container);
369 result.cells_summaries.resize(obj.result.cells_summaries.size());
370 result.contacts_summaries.resize(obj.result.contacts_summaries.size());
371 result.contacts_summaries_with_redundancy_in_periodic_box.resize(obj.result.contacts_summaries_with_redundancy_in_periodic_box.size());
372 ids_of_changed_input_spheres.resize(obj.ids_of_changed_input_spheres.size());
373 ids_of_affected_input_spheres.resize(obj.ids_of_affected_input_spheres.size());
376 #pragma omp parallel for 377 for(UnsignedInt i=0;i<obj.result.cells_summaries.size();i++)
379 result.cells_summaries[i]=obj.result.cells_summaries[i];
384 #pragma omp parallel for 385 for(UnsignedInt i=0;i<obj.result.contacts_summaries.size();i++)
387 result.contacts_summaries[i]=obj.result.contacts_summaries[i];
391 if(!obj.result.contacts_summaries_with_redundancy_in_periodic_box.empty())
393 #pragma omp parallel for 394 for(UnsignedInt i=0;i<obj.result.contacts_summaries_with_redundancy_in_periodic_box.size();i++)
396 result.contacts_summaries_with_redundancy_in_periodic_box[i]=obj.result.contacts_summaries_with_redundancy_in_periodic_box[i];
401 #pragma omp parallel for 402 for(UnsignedInt i=0;i<obj.ids_of_changed_input_spheres.size();i++)
404 ids_of_changed_input_spheres[i]=obj.ids_of_changed_input_spheres[i];
409 #pragma omp parallel for 410 for(UnsignedInt i=0;i<obj.ids_of_affected_input_spheres.size();i++)
412 ids_of_affected_input_spheres[i]=obj.ids_of_affected_input_spheres[i];
416 last_update_was_full_reinit=obj.last_update_was_full_reinit;
419 void assign(
const State& obj,
const bool assign_everything,
const std::vector<UnsignedInt>& subset_of_ids_of_spheres) noexcept
421 if(!assign_everything && subset_of_ids_of_spheres.empty())
427 || result.cells_summaries.size()!=obj.result.cells_summaries.size()
428 || result.contacts_summaries.size()!=obj.result.contacts_summaries.size()
429 || result.contacts_summaries_with_redundancy_in_periodic_box.size()!=obj.result.contacts_summaries_with_redundancy_in_periodic_box.size())
435 const bool periodic=!obj.result.contacts_summaries_with_redundancy_in_periodic_box.empty();
437 for(UnsignedInt i=0;i<subset_of_ids_of_spheres.size();i++)
439 const UnsignedInt sphere_id=subset_of_ids_of_spheres[i];
440 if(sphere_id>=result.cells_summaries.size() || (periodic && sphere_id>=result.contacts_summaries_with_redundancy_in_periodic_box.size()))
447 spheres_container.assign(obj.spheres_container, ids_of_changed_input_spheres);
450 #pragma omp parallel for 451 for(UnsignedInt i=0;i<subset_of_ids_of_spheres.size();i++)
453 const UnsignedInt sphere_id=subset_of_ids_of_spheres[i];
454 result.cells_summaries[sphere_id]=obj.result.cells_summaries[sphere_id];
455 result.contacts_summaries[sphere_id]=obj.result.contacts_summaries[sphere_id];
458 result.contacts_summaries_with_redundancy_in_periodic_box[sphere_id]=obj.result.contacts_summaries_with_redundancy_in_periodic_box[sphere_id];
463 ids_of_changed_input_spheres.resize(obj.ids_of_changed_input_spheres.size());
464 ids_of_affected_input_spheres.resize(obj.ids_of_affected_input_spheres.size());
467 #pragma omp parallel for 468 for(UnsignedInt i=0;i<obj.ids_of_changed_input_spheres.size();i++)
470 ids_of_changed_input_spheres[i]=obj.ids_of_changed_input_spheres[i];
475 #pragma omp parallel for 476 for(UnsignedInt i=0;i<obj.ids_of_affected_input_spheres.size();i++)
478 ids_of_affected_input_spheres[i]=obj.ids_of_affected_input_spheres[i];
482 last_update_was_full_reinit=obj.last_update_was_full_reinit;
485 void assign_to_undo_update(
const State& obj) noexcept
487 assign(obj, last_update_was_full_reinit, ids_of_affected_input_spheres);
490 void assign_to_apply_update(
const State& obj) noexcept
492 assign(obj, obj.last_update_was_full_reinit, obj.ids_of_affected_input_spheres);
496 void init_result_from_tessellation_result() noexcept
498 state_.ids_of_changed_input_spheres.clear();
499 state_.ids_of_affected_input_spheres.clear();
500 state_.last_update_was_full_reinit=
true;
502 state_.result.cells_summaries.swap(buffered_temporary_storage_.tessellation_result.cells_summaries);
505 state_.result.contacts_summaries.resize(state_.spheres_container.input_spheres().size());
506 for(UnsignedInt i=0;i<state_.result.contacts_summaries.size();i++)
508 state_.result.contacts_summaries[i].clear();
510 for(UnsignedInt i=0;i<buffered_temporary_storage_.tessellation_result.contacts_summaries.size();i++)
513 state_.result.contacts_summaries[cds.id_a].push_back(cds);
514 state_.result.contacts_summaries[cds.id_b].push_back(cds);
518 if(state_.spheres_container.periodic_box().enabled())
520 state_.result.contacts_summaries_with_redundancy_in_periodic_box.resize(state_.spheres_container.input_spheres().size());
521 for(UnsignedInt i=0;i<state_.result.contacts_summaries_with_redundancy_in_periodic_box.size();i++)
523 state_.result.contacts_summaries_with_redundancy_in_periodic_box[i].clear();
525 const std::vector<RadicalTessellation::ContactDescriptorSummary>& all_contacts_summaries=(buffered_temporary_storage_.tessellation_result.contacts_summaries_with_redundancy_in_periodic_box.empty() ? buffered_temporary_storage_.tessellation_result.contacts_summaries : buffered_temporary_storage_.tessellation_result.contacts_summaries_with_redundancy_in_periodic_box);
526 for(UnsignedInt i=0;i<all_contacts_summaries.size();i++)
529 if(cds.id_a<state_.result.contacts_summaries_with_redundancy_in_periodic_box.size())
531 state_.result.contacts_summaries_with_redundancy_in_periodic_box[cds.id_a].push_back(cds);
533 if(cds.id_b<state_.result.contacts_summaries_with_redundancy_in_periodic_box.size())
535 state_.result.contacts_summaries_with_redundancy_in_periodic_box[cds.id_b].push_back(cds);
541 state_.result.contacts_summaries_with_redundancy_in_periodic_box.clear();
545 void prepare_for_possible_init_or_update(
TimeRecorder& time_recorder) noexcept
547 time_recorder.reset();
549 if(backup_enabled_ && !in_sync_with_backup_)
551 state_backup_.assign_to_apply_update(state_);
552 in_sync_with_backup_=
true;
555 time_recorder.record_elapsed_miliseconds_and_reset(
"backup state");
557 state_.ids_of_changed_input_spheres.clear();
558 state_.ids_of_affected_input_spheres.clear();
559 state_.last_update_was_full_reinit=
false;
562 void update_using_current_state(
TimeRecorder& time_recorder) noexcept
564 time_recorder.reset();
566 if(involvement_of_spheres_for_update_.size()!=state_.spheres_container.input_spheres().size())
568 involvement_of_spheres_for_update_.clear();
569 involvement_of_spheres_for_update_.resize(state_.spheres_container.input_spheres().size(), 0);
572 for(UnsignedInt i=0;i<state_.ids_of_affected_input_spheres.size();i++)
574 involvement_of_spheres_for_update_[state_.ids_of_affected_input_spheres[i]]=1;
579 RadicalTessellation::construct_full_tessellation(state_.spheres_container, involvement_of_spheres_for_update_, std::vector<int>(),
false,
false, FLOATCONST(0.0), std::vector<Float>(), buffered_temporary_storage_.tessellation_result, result_graphics, time_recorder);
582 const ConditionToRemoveContact condition_to_remove_contact(involvement_of_spheres_for_update_);
584 for(UnsignedInt i=0;i<state_.ids_of_affected_input_spheres.size();i++)
586 const UnsignedInt sphere_id=state_.ids_of_affected_input_spheres[i];
588 std::vector<RadicalTessellation::ContactDescriptorSummary>& v=state_.result.contacts_summaries[sphere_id];
589 std::vector<RadicalTessellation::ContactDescriptorSummary>::iterator it=std::remove_if(v.begin(), v.end(), condition_to_remove_contact);
590 v.erase(it, v.end());
592 if(!state_.result.contacts_summaries_with_redundancy_in_periodic_box.empty())
594 std::vector<RadicalTessellation::ContactDescriptorSummary>& v=state_.result.contacts_summaries_with_redundancy_in_periodic_box[sphere_id];
595 std::vector<RadicalTessellation::ContactDescriptorSummary>::iterator it=std::remove_if(v.begin(), v.end(), condition_to_remove_contact);
596 v.erase(it, v.end());
601 if(!buffered_temporary_storage_.tessellation_result.contacts_summaries.empty())
603 for(UnsignedInt i=0;i<buffered_temporary_storage_.tessellation_result.contacts_summaries.size();i++)
606 state_.result.contacts_summaries[cds.id_a].push_back(cds);
607 state_.result.contacts_summaries[cds.id_b].push_back(cds);
610 if(!state_.result.contacts_summaries_with_redundancy_in_periodic_box.empty())
612 const std::vector<RadicalTessellation::ContactDescriptorSummary>& all_contacts_summaries=(buffered_temporary_storage_.tessellation_result.contacts_summaries_with_redundancy_in_periodic_box.empty() ? buffered_temporary_storage_.tessellation_result.contacts_summaries : buffered_temporary_storage_.tessellation_result.contacts_summaries_with_redundancy_in_periodic_box);
614 for(UnsignedInt i=0;i<all_contacts_summaries.size();i++)
617 if(cds.id_a<state_.result.contacts_summaries_with_redundancy_in_periodic_box.size())
619 state_.result.contacts_summaries_with_redundancy_in_periodic_box[cds.id_a].push_back(cds);
621 if(cds.id_b<state_.result.contacts_summaries_with_redundancy_in_periodic_box.size())
623 state_.result.contacts_summaries_with_redundancy_in_periodic_box[cds.id_b].push_back(cds);
629 time_recorder.record_elapsed_miliseconds_and_reset(
"update contacts summaries");
633 const std::vector< std::vector<RadicalTessellation::ContactDescriptorSummary> >& all_contacts_summaries=(state_.result.contacts_summaries_with_redundancy_in_periodic_box.empty() ? state_.result.contacts_summaries : state_.result.contacts_summaries_with_redundancy_in_periodic_box);
635 for(UnsignedInt i=0;i<state_.ids_of_affected_input_spheres.size();i++)
637 const UnsignedInt sphere_id=state_.ids_of_affected_input_spheres[i];
640 const std::vector<RadicalTessellation::ContactDescriptorSummary>& v=all_contacts_summaries[sphere_id];
641 for(UnsignedInt j=0;j<v.size();j++)
643 cs.add(sphere_id, v[j]);
645 cs.compute_sas(state_.spheres_container.input_spheres()[sphere_id].r);
646 if(cs.stage==0 && state_.spheres_container.all_exclusion_statuses()[sphere_id]==0 && state_.spheres_container.all_colliding_ids()[sphere_id].empty())
648 cs.compute_sas_detached(sphere_id, state_.spheres_container.input_spheres()[sphere_id].r);
652 time_recorder.record_elapsed_miliseconds_and_reset(
"update cell summaries");
655 for(UnsignedInt i=0;i<state_.ids_of_affected_input_spheres.size();i++)
657 involvement_of_spheres_for_update_[state_.ids_of_affected_input_spheres[i]]=0;
663 bool backup_enabled_;
664 bool in_sync_with_backup_;
665 std::vector<int> involvement_of_spheres_for_update_;
666 BufferedTemporaryStorage buffered_temporary_storage_;
Definition: time_recorder.h:7
Definition: updateable_radical_tessellation.h:28
Definition: radical_tessellation.h:234
Definition: updateable_radical_tessellation.h:9
Definition: updateable_radical_tessellation.h:12
Definition: spheres_container.h:11
Definition: periodic_box.h:11
Definition: radical_tessellation.h:266
Definition: basic_types_and_functions.h:19