Loading [MathJax]/extensions/TeX/newcommand.js
 deal.II version GIT relicensing-2818-g666d72c29b 2025-03-12 13:10:00+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\}}
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
property_pool.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2017 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15
19
21
23
24namespace Particles
25{
26 template <int dim, int spacedim>
27 const typename PropertyPool<dim, spacedim>::Handle
28 PropertyPool<dim, spacedim>::invalid_handle = static_cast<Handle>(-1);
29
30
31
32 template <int dim, int spacedim>
34 const unsigned int n_properties_per_slot)
35 : n_properties(n_properties_per_slot)
36 {}
37
38
39
40 template <int dim, int spacedim>
45
46
47
48 template <int dim, int spacedim>
49 void
51 {
52 const unsigned int n_open_handles =
53 locations.size() - currently_available_handles.size();
54 (void)n_open_handles;
55 Assert(n_open_handles == 0,
56 ExcMessage("This property pool currently still holds " +
57 std::to_string(n_open_handles) +
58 " open handles to memory that was allocated "
59 "via allocate_properties_array() but that has "
60 "not been returned via "
61 "deregister_particle()."));
62
63 // Clear vectors and ensure deallocation of memory
64 locations.clear();
65 locations.shrink_to_fit();
66
67 reference_locations.clear();
68 reference_locations.shrink_to_fit();
69
70 ids.clear();
71 ids.shrink_to_fit();
72
73 properties.clear();
74 properties.shrink_to_fit();
75
76 currently_available_handles.clear();
77 currently_available_handles.shrink_to_fit();
78 }
79
80
81
82 template <int dim, int spacedim>
85 {
86 Handle handle = invalid_handle;
87 if (currently_available_handles.size() > 0)
88 {
89 handle = currently_available_handles.back();
90 currently_available_handles.pop_back();
91 }
92 else
93 {
94 handle = locations.size();
95
96 locations.resize(locations.size() + 1);
97 reference_locations.resize(reference_locations.size() + 1);
98 ids.resize(ids.size() + 1);
99 properties.resize(properties.size() + n_properties);
100 }
101
102 // Then initialize whatever slot we have taken with invalid locations,
103 // but initialize properties with zero.
104 set_location(handle, numbers::signaling_nan<Point<spacedim>>());
105 set_reference_location(handle, numbers::signaling_nan<Point<dim>>());
106 set_id(handle, numbers::invalid_unsigned_int);
107 for (double &x : get_properties(handle))
108 x = 0;
109
110 return handle;
111 }
112
113
114
115 template <int dim, int spacedim>
116 void
118 {
120 handle != invalid_handle,
122 "This handle is invalid and cannot be deallocated. This can happen if the "
123 "handle was deallocated already before calling this function."));
124
125 Assert(
126 currently_available_handles.size() < locations.size(),
128 "Trying to deallocate a particle when none are allocated. This can happen if all "
129 "handles were deallocated already before calling this function."));
130
131 currently_available_handles.push_back(handle);
132 handle = invalid_handle;
133
134 // If this was the last handle, resize containers to 0.
135 // This guarantees that all future properties
136 // are allocated in a sorted way without requiring reallocation.
137 if (currently_available_handles.size() == locations.size())
138 {
139 currently_available_handles.clear();
140 properties.clear();
141 locations.clear();
142 reference_locations.clear();
143 ids.clear();
144 }
145 }
146
147
148
149 template <int dim, int spacedim>
150 void
152 {
153 locations.reserve(size);
154 reference_locations.reserve(size);
155 properties.reserve(size * n_properties);
156 ids.reserve(size);
157 }
158
159
160
161 template <int dim, int spacedim>
162 unsigned int
164 {
165 return n_properties;
166 }
167
168
169
170 template <int dim, int spacedim>
171 unsigned int
173 {
174 Assert(locations.size() == reference_locations.size(),
175 ExcMessage("Number of registered locations is not equal to number "
176 "of registered reference locations."));
177
178 Assert(locations.size() == ids.size(),
179 ExcMessage("Number of registered locations is not equal to number "
180 "of registered ids."));
181
182 Assert(locations.size() * n_properties == properties.size(),
183 ExcMessage("Number of registered locations is not equal to number "
184 "of registered property slots."));
185
186 return locations.size() - currently_available_handles.size();
187 }
188
189
190
191 template <int dim, int spacedim>
192 void
194 const std::vector<Handle> &handles_to_sort)
195 {
196 std::vector<Point<spacedim>> sorted_locations;
197 std::vector<Point<dim>> sorted_reference_locations;
198 std::vector<types::particle_index> sorted_ids;
199 std::vector<double> sorted_properties;
200
201 sorted_locations.reserve(locations.size());
202 sorted_reference_locations.reserve(reference_locations.size());
203 sorted_ids.reserve(ids.size());
204 sorted_properties.reserve(properties.size());
205
206 for (const auto &handle : handles_to_sort)
207 {
208 Assert(handle != invalid_handle,
210 "Invalid handle detected during sorting particle memory."));
211
212 sorted_locations.push_back(locations[handle]);
213 sorted_reference_locations.push_back(reference_locations[handle]);
214 sorted_ids.push_back(ids[handle]);
215
216 for (unsigned int j = 0; j < n_properties; ++j)
217 sorted_properties.push_back(properties[handle * n_properties + j]);
218 }
219
220 Assert(sorted_locations.size() ==
221 locations.size() - currently_available_handles.size(),
222 ExcMessage("Number of sorted property handles is not equal to "
223 "number of currently registered handles: " +
224 std::to_string(sorted_locations.size()) + " vs " +
225 std::to_string(locations.size()) + " - " +
226 std::to_string(currently_available_handles.size())));
227
228 locations = std::move(sorted_locations);
229 reference_locations = std::move(sorted_reference_locations);
230 ids = std::move(sorted_ids);
231 properties = std::move(sorted_properties);
232
233 currently_available_handles.clear();
234 }
235
236
237 // Instantiate the class for all reasonable template arguments
238 template class PropertyPool<1, 1>;
239 template class PropertyPool<1, 2>;
240 template class PropertyPool<1, 3>;
241 template class PropertyPool<2, 2>;
242 template class PropertyPool<2, 3>;
243 template class PropertyPool<3, 3>;
244} // namespace Particles
unsigned int n_properties_per_slot() const
unsigned int n_registered_slots() const
void deregister_particle(Handle &handle)
void reserve(const std::size_t size)
PropertyPool(const unsigned int n_properties_per_slot)
void sort_memory_slots(const std::vector< Handle > &handles_to_sort)
Definition point.h:113
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
#define Assert(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
std::size_t size
Definition mpi.cc:745
constexpr unsigned int invalid_unsigned_int
Definition types.h:232
T signaling_nan()