faunus
updateable_radical_tessellation.h
1 #ifndef VORONOTALT_UPDATEABLE_RADICAL_TESSELLATION_H_
2 #define VORONOTALT_UPDATEABLE_RADICAL_TESSELLATION_H_
3 
4 #include "radical_tessellation.h"
5 
6 namespace voronotalt
7 {
8 
10 {
11 public:
12  struct Result
13  {
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;
17 
18  Result() noexcept
19  {
20  }
21 
22  bool empty() noexcept
23  {
24  return (cells_summaries.empty() || contacts_summaries.empty());
25  }
26  };
27 
29  {
32 
33  ResultSummary() noexcept
34  {
35  }
36  };
37 
38  UpdateableRadicalTessellation() noexcept : backup_enabled_(false), in_sync_with_backup_(false)
39  {
40  }
41 
42  explicit UpdateableRadicalTessellation(const bool backup_enabled) noexcept : backup_enabled_(backup_enabled), in_sync_with_backup_(false)
43  {
44  }
45 
46  bool init(const std::vector<SimpleSphere>& input_spheres) noexcept
47  {
48  TimeRecorder time_recorder;
49  return init(input_spheres, time_recorder);
50  }
51 
52  bool init(const std::vector<SimpleSphere>& input_spheres, TimeRecorder& time_recorder) noexcept
53  {
54  return init(input_spheres, PeriodicBox(), time_recorder);
55  }
56 
57  bool init(const std::vector<SimpleSphere>& input_spheres, const PeriodicBox& periodic_box) noexcept
58  {
59  TimeRecorder time_recorder;
60  return init(input_spheres, periodic_box, time_recorder);
61  }
62 
63  bool init(const std::vector<SimpleSphere>& input_spheres, const PeriodicBox& periodic_box, TimeRecorder& time_recorder) noexcept
64  {
65  prepare_for_possible_init_or_update(time_recorder);
66 
67  state_.spheres_container.init(input_spheres, periodic_box, time_recorder);
68 
69  in_sync_with_backup_=false;
70 
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);
73 
74  involvement_of_spheres_for_update_.clear();
75 
76  init_result_from_tessellation_result();
77 
78  return !state_.result.empty();
79  }
80 
81  bool update(const std::vector<SimpleSphere>& new_input_spheres) noexcept
82  {
83  TimeRecorder time_recorder;
84  return update(new_input_spheres, std::vector<UnsignedInt>(), false, time_recorder);
85  }
86 
87  bool update(const std::vector<SimpleSphere>& new_input_spheres, TimeRecorder& time_recorder) noexcept
88  {
89  return update(new_input_spheres, std::vector<UnsignedInt>(), false, time_recorder);
90  }
91 
92  bool update(const std::vector<SimpleSphere>& new_input_spheres, const std::vector<UnsignedInt>& ids_of_changed_input_spheres) noexcept
93  {
94  TimeRecorder time_recorder;
95  return update(new_input_spheres, ids_of_changed_input_spheres, true, time_recorder);
96  }
97 
98  bool update(const std::vector<SimpleSphere>& new_input_spheres, const std::vector<UnsignedInt>& ids_of_changed_input_spheres, TimeRecorder& time_recorder) noexcept
99  {
100  return update(new_input_spheres, ids_of_changed_input_spheres, true, time_recorder);
101  }
102 
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
104  {
105  prepare_for_possible_init_or_update(time_recorder);
106 
107  if(trust_provided_ids_of_changed_input_spheres && provided_ids_of_changed_input_spheres.empty())
108  {
109  return false;
110  }
111 
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))
113  {
114  return false;
115  }
116 
117  in_sync_with_backup_=false;
118 
119  if(state_.ids_of_affected_input_spheres.empty())
120  {
121  RadicalTessellation::ResultGraphics result_graphics;
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();
124  }
125  else
126  {
127  update_using_current_state(time_recorder);
128  }
129 
130  return true;
131  }
132 
133  bool update_by_setting_exclusion_mask(const UnsignedInt id_of_targeted_input_sphere, const bool new_exclusion_status) noexcept
134  {
135  TimeRecorder time_recorder;
136  return update_by_setting_exclusion_mask(id_of_targeted_input_sphere, new_exclusion_status, time_recorder);
137  }
138 
139  bool update_by_setting_exclusion_mask(const UnsignedInt id_of_targeted_input_sphere, const bool new_exclusion_status, TimeRecorder& time_recorder) noexcept
140  {
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))
144  {
145  return false;
146  }
147 
148  prepare_for_possible_init_or_update(time_recorder);
149 
150  if(new_exclusion_status)
151  {
152  if(!state_.spheres_container.update_by_setting_exclusion_status(id_of_targeted_input_sphere, true))
153  {
154  return false;
155  }
156 
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);
159 
160  for(UnsignedInt i=0;i<state_.result.contacts_summaries[id_of_targeted_input_sphere].size();i++)
161  {
162  const RadicalTessellation::ContactDescriptorSummary& cds=state_.result.contacts_summaries[id_of_targeted_input_sphere][i];
163  if(cds.id_a!=id_of_targeted_input_sphere)
164  {
165  state_.ids_of_affected_input_spheres.push_back(cds.id_a);
166  }
167  else if(cds.id_b!=id_of_targeted_input_sphere)
168  {
169  state_.ids_of_affected_input_spheres.push_back(cds.id_b);
170  }
171  }
172  }
173  else
174  {
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))
176  {
177  return false;
178  }
179  }
180 
181  in_sync_with_backup_=false;
182 
183  update_using_current_state(time_recorder);
184 
185  return true;
186  }
187 
188  bool restore_from_backup() noexcept
189  {
190  if(backup_enabled_ && !in_sync_with_backup_)
191  {
192  state_.assign_to_undo_update(state_backup_);
193  in_sync_with_backup_=true;
194  }
195 
196  return in_sync_with_backup_;
197  }
198 
199  bool calculate_second_order_cell_volumes(std::vector< std::vector<Float> >& all_result_volumes_for_contacts_summaries) noexcept
200  {
201  all_result_volumes_for_contacts_summaries.clear();
202 
203  if(!backup_enabled_ || state_.result.empty())
204  {
205  return false;
206  }
207 
208  const UnsignedInt N=state_.result.contacts_summaries.size();
209 
210  std::vector< std::vector<UnsignedInt> > all_neighbor_ids(N);
211  std::vector< std::vector<Float> > all_volumes_after_masking(N);
212 
213  for(UnsignedInt i=0;i<N;i++)
214  {
215  std::vector<UnsignedInt>& i_neighbor_ids=all_neighbor_ids[i];
216 
217  {
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++)
221  {
222  i_neighbor_ids[j]=(cdss[j].id_a!=i ? cdss[j].id_a : cdss[j].id_b);
223  }
224  }
225 
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));
228 
229  if(update_by_setting_exclusion_mask(i, true))
230  {
231  for(UnsignedInt j=0;j<i_neighbor_ids.size();j++)
232  {
233  i_volumes_after_masking[j]=state_.result.cells_summaries[i_neighbor_ids[j]].sas_inside_volume;
234  }
235  restore_from_backup();
236  }
237  }
238 
239  all_result_volumes_for_contacts_summaries.resize(N);
240 
241  for(UnsignedInt i=0;i<N;i++)
242  {
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++)
246  {
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++)
252  {
253  if(all_neighbor_ids[neighbor_id][relative_i]==i)
254  {
255  i_volume_after_masking_neighbor=all_volumes_after_masking[neighbor_id][relative_i];
256  }
257  }
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);
259  }
260  }
261 
262  return true;
263  }
264 
265  bool backup_enabled() const noexcept
266  {
267  return backup_enabled_;
268  }
269 
270  bool in_sync_with_backup() const noexcept
271  {
272  return in_sync_with_backup_;
273  }
274 
275  const std::vector<SimpleSphere>& input_spheres() const noexcept
276  {
277  return state_.spheres_container.input_spheres();
278  }
279 
280  bool exclusion_status_of_input_sphere(const UnsignedInt id_of_input_sphere) const noexcept
281  {
282  return (id_of_input_sphere<state_.spheres_container.all_exclusion_statuses().size() && state_.spheres_container.all_exclusion_statuses()[id_of_input_sphere]>0);
283  }
284 
285  const Result& result() const noexcept
286  {
287  return state_.result;
288  }
289 
290  ResultSummary result_summary() const noexcept
291  {
292  ResultSummary result_summary;
293  for(UnsignedInt i=0;i<state_.result.contacts_summaries.size();i++)
294  {
295  for(UnsignedInt j=0;j<state_.result.contacts_summaries[i].size();j++)
296  {
297  const RadicalTessellation::ContactDescriptorSummary& cds=state_.result.contacts_summaries[i][j];
298  if(cds.id_a==i)
299  {
300  result_summary.total_contacts_summary.add(cds);
301  }
302  }
303  }
304  for(UnsignedInt i=0;i<state_.result.cells_summaries.size();i++)
305  {
306  result_summary.total_cells_summary.add(state_.result.cells_summaries[i]);
307  }
308  return result_summary;
309  }
310 
311  const std::vector<UnsignedInt>& last_update_ids_of_changed_input_spheres() const noexcept
312  {
313  return state_.ids_of_changed_input_spheres;
314  }
315 
316  const std::vector<UnsignedInt>& last_update_ids_of_affected_input_spheres() const noexcept
317  {
318  return state_.ids_of_affected_input_spheres;
319  }
320 
321  bool last_update_was_full_reinit() const noexcept
322  {
323  return state_.last_update_was_full_reinit;
324  }
325 
326 private:
327  struct BufferedTemporaryStorage
328  {
329  RadicalTessellation::Result tessellation_result;
330 
331  void clear() noexcept
332  {
333  tessellation_result.clear();
334  }
335  };
336 
337  class ConditionToRemoveContact
338  {
339  public:
340  explicit ConditionToRemoveContact(const std::vector<int>& involvement) noexcept : involvement_(involvement)
341  {
342  }
343 
344  bool operator()(const RadicalTessellation::ContactDescriptorSummary& cds) noexcept
345  {
346  return (involvement_.empty() || (involvement_[cds.id_a%involvement_.size()]>0 && involvement_[cds.id_b%involvement_.size()]>0));
347  }
348 
349  private:
350  const std::vector<int>& involvement_;
351  };
352 
353  struct State
354  {
355  SpheresContainer spheres_container;
356  Result result;
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;
360 
361  State() noexcept : last_update_was_full_reinit(true)
362  {
363  }
364 
365  void assign(const State& obj) noexcept
366  {
367  spheres_container.assign(obj.spheres_container);
368 
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());
374 
375  {
376  #pragma omp parallel for
377  for(UnsignedInt i=0;i<obj.result.cells_summaries.size();i++)
378  {
379  result.cells_summaries[i]=obj.result.cells_summaries[i];
380  }
381  }
382 
383  {
384  #pragma omp parallel for
385  for(UnsignedInt i=0;i<obj.result.contacts_summaries.size();i++)
386  {
387  result.contacts_summaries[i]=obj.result.contacts_summaries[i];
388  }
389  }
390 
391  if(!obj.result.contacts_summaries_with_redundancy_in_periodic_box.empty())
392  {
393  #pragma omp parallel for
394  for(UnsignedInt i=0;i<obj.result.contacts_summaries_with_redundancy_in_periodic_box.size();i++)
395  {
396  result.contacts_summaries_with_redundancy_in_periodic_box[i]=obj.result.contacts_summaries_with_redundancy_in_periodic_box[i];
397  }
398  }
399 
400  {
401  #pragma omp parallel for
402  for(UnsignedInt i=0;i<obj.ids_of_changed_input_spheres.size();i++)
403  {
404  ids_of_changed_input_spheres[i]=obj.ids_of_changed_input_spheres[i];
405  }
406  }
407 
408  {
409  #pragma omp parallel for
410  for(UnsignedInt i=0;i<obj.ids_of_affected_input_spheres.size();i++)
411  {
412  ids_of_affected_input_spheres[i]=obj.ids_of_affected_input_spheres[i];
413  }
414  }
415 
416  last_update_was_full_reinit=obj.last_update_was_full_reinit;
417  }
418 
419  void assign(const State& obj, const bool assign_everything, const std::vector<UnsignedInt>& subset_of_ids_of_spheres) noexcept
420  {
421  if(!assign_everything && subset_of_ids_of_spheres.empty())
422  {
423  return;
424  }
425 
426  if(assign_everything
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())
430  {
431  assign(obj);
432  return;
433  }
434 
435  const bool periodic=!obj.result.contacts_summaries_with_redundancy_in_periodic_box.empty();
436 
437  for(UnsignedInt i=0;i<subset_of_ids_of_spheres.size();i++)
438  {
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()))
441  {
442  assign(obj);
443  return;
444  }
445  }
446 
447  spheres_container.assign(obj.spheres_container, ids_of_changed_input_spheres);
448 
449  {
450  #pragma omp parallel for
451  for(UnsignedInt i=0;i<subset_of_ids_of_spheres.size();i++)
452  {
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];
456  if(periodic)
457  {
458  result.contacts_summaries_with_redundancy_in_periodic_box[sphere_id]=obj.result.contacts_summaries_with_redundancy_in_periodic_box[sphere_id];
459  }
460  }
461  }
462 
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());
465 
466  {
467  #pragma omp parallel for
468  for(UnsignedInt i=0;i<obj.ids_of_changed_input_spheres.size();i++)
469  {
470  ids_of_changed_input_spheres[i]=obj.ids_of_changed_input_spheres[i];
471  }
472  }
473 
474  {
475  #pragma omp parallel for
476  for(UnsignedInt i=0;i<obj.ids_of_affected_input_spheres.size();i++)
477  {
478  ids_of_affected_input_spheres[i]=obj.ids_of_affected_input_spheres[i];
479  }
480  }
481 
482  last_update_was_full_reinit=obj.last_update_was_full_reinit;
483  }
484 
485  void assign_to_undo_update(const State& obj) noexcept
486  {
487  assign(obj, last_update_was_full_reinit, ids_of_affected_input_spheres);
488  }
489 
490  void assign_to_apply_update(const State& obj) noexcept
491  {
492  assign(obj, obj.last_update_was_full_reinit, obj.ids_of_affected_input_spheres);
493  }
494  };
495 
496  void init_result_from_tessellation_result() noexcept
497  {
498  state_.ids_of_changed_input_spheres.clear();
499  state_.ids_of_affected_input_spheres.clear();
500  state_.last_update_was_full_reinit=true;
501 
502  state_.result.cells_summaries.swap(buffered_temporary_storage_.tessellation_result.cells_summaries);
503 
504  {
505  state_.result.contacts_summaries.resize(state_.spheres_container.input_spheres().size());
506  for(UnsignedInt i=0;i<state_.result.contacts_summaries.size();i++)
507  {
508  state_.result.contacts_summaries[i].clear();
509  }
510  for(UnsignedInt i=0;i<buffered_temporary_storage_.tessellation_result.contacts_summaries.size();i++)
511  {
512  const RadicalTessellation::ContactDescriptorSummary& cds=buffered_temporary_storage_.tessellation_result.contacts_summaries[i];
513  state_.result.contacts_summaries[cds.id_a].push_back(cds);
514  state_.result.contacts_summaries[cds.id_b].push_back(cds);
515  }
516  }
517 
518  if(state_.spheres_container.periodic_box().enabled())
519  {
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++)
522  {
523  state_.result.contacts_summaries_with_redundancy_in_periodic_box[i].clear();
524  }
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++)
527  {
528  const RadicalTessellation::ContactDescriptorSummary& cds=all_contacts_summaries[i];
529  if(cds.id_a<state_.result.contacts_summaries_with_redundancy_in_periodic_box.size())
530  {
531  state_.result.contacts_summaries_with_redundancy_in_periodic_box[cds.id_a].push_back(cds);
532  }
533  if(cds.id_b<state_.result.contacts_summaries_with_redundancy_in_periodic_box.size())
534  {
535  state_.result.contacts_summaries_with_redundancy_in_periodic_box[cds.id_b].push_back(cds);
536  }
537  }
538  }
539  else
540  {
541  state_.result.contacts_summaries_with_redundancy_in_periodic_box.clear();
542  }
543  }
544 
545  void prepare_for_possible_init_or_update(TimeRecorder& time_recorder) noexcept
546  {
547  time_recorder.reset();
548 
549  if(backup_enabled_ && !in_sync_with_backup_)
550  {
551  state_backup_.assign_to_apply_update(state_);
552  in_sync_with_backup_=true;
553  }
554 
555  time_recorder.record_elapsed_miliseconds_and_reset("backup state");
556 
557  state_.ids_of_changed_input_spheres.clear();
558  state_.ids_of_affected_input_spheres.clear();
559  state_.last_update_was_full_reinit=false;
560  }
561 
562  void update_using_current_state(TimeRecorder& time_recorder) noexcept
563  {
564  time_recorder.reset();
565 
566  if(involvement_of_spheres_for_update_.size()!=state_.spheres_container.input_spheres().size())
567  {
568  involvement_of_spheres_for_update_.clear();
569  involvement_of_spheres_for_update_.resize(state_.spheres_container.input_spheres().size(), 0);
570  }
571 
572  for(UnsignedInt i=0;i<state_.ids_of_affected_input_spheres.size();i++)
573  {
574  involvement_of_spheres_for_update_[state_.ids_of_affected_input_spheres[i]]=1;
575  }
576 
577  {
578  RadicalTessellation::ResultGraphics result_graphics;
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);
580 
581  {
582  const ConditionToRemoveContact condition_to_remove_contact(involvement_of_spheres_for_update_);
583 
584  for(UnsignedInt i=0;i<state_.ids_of_affected_input_spheres.size();i++)
585  {
586  const UnsignedInt sphere_id=state_.ids_of_affected_input_spheres[i];
587  {
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());
591  }
592  if(!state_.result.contacts_summaries_with_redundancy_in_periodic_box.empty())
593  {
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());
597  }
598  }
599  }
600 
601  if(!buffered_temporary_storage_.tessellation_result.contacts_summaries.empty())
602  {
603  for(UnsignedInt i=0;i<buffered_temporary_storage_.tessellation_result.contacts_summaries.size();i++)
604  {
605  const RadicalTessellation::ContactDescriptorSummary& cds=buffered_temporary_storage_.tessellation_result.contacts_summaries[i];
606  state_.result.contacts_summaries[cds.id_a].push_back(cds);
607  state_.result.contacts_summaries[cds.id_b].push_back(cds);
608  }
609 
610  if(!state_.result.contacts_summaries_with_redundancy_in_periodic_box.empty())
611  {
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);
613 
614  for(UnsignedInt i=0;i<all_contacts_summaries.size();i++)
615  {
616  const RadicalTessellation::ContactDescriptorSummary& cds=all_contacts_summaries[i];
617  if(cds.id_a<state_.result.contacts_summaries_with_redundancy_in_periodic_box.size())
618  {
619  state_.result.contacts_summaries_with_redundancy_in_periodic_box[cds.id_a].push_back(cds);
620  }
621  if(cds.id_b<state_.result.contacts_summaries_with_redundancy_in_periodic_box.size())
622  {
623  state_.result.contacts_summaries_with_redundancy_in_periodic_box[cds.id_b].push_back(cds);
624  }
625  }
626  }
627  }
628 
629  time_recorder.record_elapsed_miliseconds_and_reset("update contacts summaries");
630  }
631 
632  {
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);
634 
635  for(UnsignedInt i=0;i<state_.ids_of_affected_input_spheres.size();i++)
636  {
637  const UnsignedInt sphere_id=state_.ids_of_affected_input_spheres[i];
638  RadicalTessellation::CellContactDescriptorsSummary& cs=state_.result.cells_summaries[sphere_id];
640  const std::vector<RadicalTessellation::ContactDescriptorSummary>& v=all_contacts_summaries[sphere_id];
641  for(UnsignedInt j=0;j<v.size();j++)
642  {
643  cs.add(sphere_id, v[j]);
644  }
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())
647  {
648  cs.compute_sas_detached(sphere_id, state_.spheres_container.input_spheres()[sphere_id].r);
649  }
650  }
651 
652  time_recorder.record_elapsed_miliseconds_and_reset("update cell summaries");
653  }
654 
655  for(UnsignedInt i=0;i<state_.ids_of_affected_input_spheres.size();i++)
656  {
657  involvement_of_spheres_for_update_[state_.ids_of_affected_input_spheres[i]]=0;
658  }
659  }
660 
661  State state_;
662  State state_backup_;
663  bool backup_enabled_;
664  bool in_sync_with_backup_;
665  std::vector<int> involvement_of_spheres_for_update_;
666  BufferedTemporaryStorage buffered_temporary_storage_;
667 };
668 
669 }
670 
671 #endif /* VORONOTALT_UPDATEABLE_RADICAL_TESSELLATION_H_ */
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