Reference documentation for deal.II version GIT 5983d193e2 2023-05-27 16:50:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
property_pool.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2017 - 2021 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
18 
20 
22 
23 namespace Particles
24 {
25  template <int dim, int spacedim>
27  PropertyPool<dim, spacedim>::invalid_handle = static_cast<Handle>(-1);
28 
29 
30 
31  template <int dim, int spacedim>
33  const unsigned int n_properties_per_slot)
34  : n_properties(n_properties_per_slot)
35  {}
36 
37 
38 
39  template <int dim, int spacedim>
41  {
42  clear();
43  }
44 
45 
46 
47  template <int dim, int spacedim>
48  void
50  {
51  if (n_properties > 0)
52  {
53  const unsigned int n_open_handles =
54  properties.size() / n_properties - currently_available_handles.size();
55  (void)n_open_handles;
56  AssertThrow(n_open_handles == 0,
57  ExcMessage("This property pool currently still holds " +
58  std::to_string(n_open_handles) +
59  " open handles to memory that was allocated "
60  "via allocate_properties_array() but that has "
61  "not been returned via "
62  "deregister_particle()."));
63  }
64 
65  // Clear vectors and ensure deallocation of memory
66  locations.clear();
67  locations.shrink_to_fit();
68 
69  reference_locations.clear();
70  reference_locations.shrink_to_fit();
71 
72  ids.clear();
73  ids.shrink_to_fit();
74 
75  properties.clear();
76  properties.shrink_to_fit();
77 
78  currently_available_handles.clear();
79  currently_available_handles.shrink_to_fit();
80  }
81 
82 
83 
84  template <int dim, int spacedim>
87  {
88  Handle handle = invalid_handle;
89  if (currently_available_handles.size() > 0)
90  {
91  handle = currently_available_handles.back();
92  currently_available_handles.pop_back();
93  }
94  else
95  {
96  handle = locations.size();
97 
98  locations.resize(locations.size() + 1);
99  reference_locations.resize(reference_locations.size() + 1);
100  ids.resize(ids.size() + 1);
101  properties.resize(properties.size() + n_properties);
102  }
103 
104  // Then initialize whatever slot we have taken with invalid locations,
105  // but initialize properties with zero.
106  set_location(handle, numbers::signaling_nan<Point<spacedim>>());
107  set_reference_location(handle, numbers::signaling_nan<Point<dim>>());
108  set_id(handle, numbers::invalid_unsigned_int);
109  for (double &x : get_properties(handle))
110  x = 0;
111 
112  return handle;
113  }
114 
115 
116 
117  template <int dim, int spacedim>
118  void
120  {
121  Assert(
122  handle != invalid_handle,
123  ExcMessage(
124  "This handle is invalid and cannot be deallocated. This can happen if the "
125  "handle was deallocated already before calling this function."));
126 
128  currently_available_handles.size() < locations.size(),
129  ExcMessage(
130  "Trying to deallocate a particle when none are allocated. This can happen if all "
131  "handles were deallocated already before calling this function."));
132 
133  currently_available_handles.push_back(handle);
134  handle = invalid_handle;
135 
136  // If this was the last handle, resize containers to 0.
137  // This guarantees that all future properties
138  // are allocated in a sorted way without requiring reallocation.
139  if (currently_available_handles.size() == locations.size())
140  {
141  currently_available_handles.clear();
142  properties.clear();
143  locations.clear();
144  reference_locations.clear();
145  ids.clear();
146  }
147  }
148 
149 
150 
151  template <int dim, int spacedim>
152  void
153  PropertyPool<dim, spacedim>::reserve(const std::size_t size)
154  {
155  locations.reserve(size);
156  reference_locations.reserve(size);
157  properties.reserve(size * n_properties);
158  ids.reserve(size);
159  }
160 
161 
162 
163  template <int dim, int spacedim>
164  unsigned int
166  {
167  return n_properties;
168  }
169 
170 
171 
172  template <int dim, int spacedim>
173  unsigned int
175  {
176  Assert(locations.size() == reference_locations.size(),
177  ExcMessage("Number of registered locations is not equal to number "
178  "of registered reference locations."));
179 
180  Assert(locations.size() == ids.size(),
181  ExcMessage("Number of registered locations is not equal to number "
182  "of registered ids."));
183 
184  Assert(locations.size() * n_properties == properties.size(),
185  ExcMessage("Number of registered locations is not equal to number "
186  "of registered property slots."));
187 
188  return locations.size() - currently_available_handles.size();
189  }
190 
191 
192 
193  template <int dim, int spacedim>
194  void
196  const std::vector<Handle> &handles_to_sort)
197  {
198  std::vector<Point<spacedim>> sorted_locations;
199  std::vector<Point<dim>> sorted_reference_locations;
200  std::vector<types::particle_index> sorted_ids;
201  std::vector<double> sorted_properties;
202 
203  sorted_locations.reserve(locations.size());
204  sorted_reference_locations.reserve(reference_locations.size());
205  sorted_ids.reserve(ids.size());
206  sorted_properties.reserve(properties.size());
207 
208  for (auto &handle : handles_to_sort)
209  {
210  Assert(handle != invalid_handle,
211  ExcMessage(
212  "Invalid handle detected during sorting particle memory."));
213 
214  sorted_locations.push_back(locations[handle]);
215  sorted_reference_locations.push_back(reference_locations[handle]);
216  sorted_ids.push_back(ids[handle]);
217 
218  for (unsigned int j = 0; j < n_properties; ++j)
219  sorted_properties.push_back(properties[handle * n_properties + j]);
220  }
221 
222  Assert(sorted_locations.size() ==
223  locations.size() - currently_available_handles.size(),
224  ExcMessage("Number of sorted property handles is not equal to "
225  "number of currently registered handles: " +
226  std::to_string(sorted_locations.size()) + " vs " +
227  std::to_string(locations.size()) + " - " +
228  std::to_string(currently_available_handles.size())));
229 
230  locations = std::move(sorted_locations);
231  reference_locations = std::move(sorted_reference_locations);
232  ids = std::move(sorted_ids);
233  properties = std::move(sorted_properties);
234 
235  currently_available_handles.clear();
236  }
237 
238 
239  // Instantiate the class for all reasonable template arguments
240  template class PropertyPool<1, 1>;
241  template class PropertyPool<1, 2>;
242  template class PropertyPool<1, 3>;
243  template class PropertyPool<2, 2>;
244  template class PropertyPool<2, 3>;
245  template class PropertyPool<3, 3>;
246 } // namespace Particles
void reserve(const std::size_t size)
PropertyPool(const unsigned int n_properties_per_slot)
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:474
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:475
#define Assert(cond, exc)
Definition: exceptions.h:1614
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1703
std::string to_string(const T &t)
Definition: patterns.h:2392
static const unsigned int invalid_unsigned_int
Definition: types.h:213
T signaling_nan()