MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
particlevector.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#include "particlevector.hpp"
13
14namespace mfem
15{
16
17void ParticleVector::GrowSize(int min_num_vectors, bool keep_data)
18{
19 const int nsize = std::max(min_num_vectors*vdim, 2 * data.Capacity());
21 if (keep_data) { p.CopyFrom(data, size); }
22 p.UseDevice(data.UseDevice());
23 data.Delete();
24 data = p;
25}
26
28 : ParticleVector(vdim_, ordering_, 0) { }
29
31 int num_nodes)
32 : Vector(num_nodes*vdim_), vdim(vdim_), ordering(ordering_)
33{
35}
36
38 const Vector &vec)
39 : Vector(vec), vdim(vdim_), ordering(ordering_)
40{
41 MFEM_ASSERT(vec.Size() % vdim == 0,
42 "Incompatible Vector size of " << vec.Size() << " given vdim " << vdim);
43}
44
45void ParticleVector::GetValues(int i, Vector &nvals) const
46{
47 nvals.SetSize(vdim);
48
50 {
51 int nv = GetNumParticles();
52 for (int c = 0; c < vdim; c++)
53 {
54 nvals[c] = Vector::operator[](i+nv*c);
55 }
56 }
57 else
58 {
59 for (int c = 0; c < vdim; c++)
60 {
61 nvals[c] = Vector::operator[](c+vdim*i);
62 }
63 }
64}
65
67{
68 MFEM_ASSERT(ordering == Ordering::byVDIM,
69 "GetValuesRef only valid when ordering byVDIM.");
70
71 nref.MakeRef(*this, i*vdim, vdim);
72}
73
75{
76 int vdim_temp = vdim;
77
78 // For byNODES: Treat each component as a vector temporarily
79 // For byVDIM: Treat each vector as a component temporarily
83
84 GetValues(vd, comp);
85
86 // Reset ordering back to original
89
90 vdim = vdim_temp;
91}
92
94{
95 MFEM_ASSERT(ordering == Ordering::byNODES,
96 "GetComponentsRef only valid when ordering byNODES.");
97 nref.MakeRef(*this, vd*GetNumParticles(), GetNumParticles());
98}
99
100void ParticleVector::SetValues(int i, const Vector &nvals)
101{
103 {
104 int nv = GetNumParticles();
105 for (int c = 0; c < vdim; c++)
106 {
107 Vector::operator[](i + c*nv) = nvals[c];
108 }
109 }
110 else
111 {
112 for (int c = 0; c < vdim; c++)
113 {
114 Vector::operator[](c + i*vdim) = nvals[c];
115 }
116 }
117}
118
119void ParticleVector::SetComponents(int vd, const Vector &comp)
120{
121 int vdim_temp = vdim;
122
123 // For byNODES: Treat each component as a vector temporarily
124 // For byVDIM: Treat each vector as a component temporarily
128
129 SetValues(vd, comp);
130
131 // Reset ordering back to original
134
135 vdim = vdim_temp;
136}
137
139{
140 MFEM_ASSERT(i < GetNumParticles(),
141 "Particle index " << i <<
142 " is invalid for number of particles " << GetNumParticles());
143 MFEM_ASSERT(comp < vdim,
144 "Component index " << comp <<
145 " is invalid for vector dimension " << vdim);
146
148 {
149 return Vector::operator[](i + comp*GetNumParticles());
150 }
151 else
152 {
153 return Vector::operator[](comp + i*vdim);
154 }
155}
156
157const real_t& ParticleVector::operator()(int i, int comp) const
158{
159 MFEM_ASSERT(i < GetNumParticles(),
160 "Particle index " << i <<
161 " is invalid for number of particles " << GetNumParticles());
162 MFEM_ASSERT(comp < vdim,
163 "Component index " << comp <<
164 " is invalid for vector dimension " << vdim);
165
167 {
168 return Vector::operator[](i + comp*GetNumParticles());
169 }
170 else
171 {
172 return Vector::operator[](comp + i*vdim);
173 }
174}
175
177{
178 if (indices.Size() == 0) { return; }
179 // Convert list index array of "ldofs" to "vdofs"
180 Array<int> v_list;
181 v_list.Reserve(indices.Size()*vdim);
182 MFEM_VERIFY(indices.Max() < GetNumParticles(),
183 "Particle index " << indices.Max() <<
184 " is out-of-range for number of particles " <<
187 {
188 for (int l = 0; l < indices.Size(); l++)
189 {
190 for (int vd = 0; vd < vdim; vd++)
191 {
192 v_list.Append(Ordering::Map<Ordering::byNODES>(GetNumParticles(),
193 vdim,
194 indices[l], vd));
195 }
196 }
197 }
198 else
199 {
200 for (int l = 0; l < indices.Size(); l++)
201 {
202 for (int vd = 0; vd < vdim; vd++)
203 {
204 v_list.Append(Ordering::Map<Ordering::byVDIM>(GetNumParticles(),
205 vdim,
206 indices[l],
207 vd));
208 }
209 }
210 }
211
212 Vector::DeleteAt(v_list);
213}
214
215void ParticleVector::SetVDim(int vdim_, bool keep_data)
216{
217 if (!keep_data)
218 {
219 int num_particles = GetNumParticles();
220 vdim = vdim_;
221 Vector::SetSize(num_particles*vdim_);
222 return;
223 }
224
225 // Reorder/shift existing entries
226 // For byNODES: Treat each component as a vector temporarily
227 // For byVDIM: Treat each vector as a component temporarily
231
232 SetNumParticles(vdim_, keep_data);
233
234 // Reset ordering back to original
237
238 vdim = vdim_;
239}
240
241void ParticleVector::SetOrdering(Ordering::Type ordering_, bool keep_data)
242{
243 if (keep_data)
244 {
245 Ordering::Reorder(*this, vdim, ordering, ordering_);
246 }
247 ordering = ordering_;
248}
249
250void ParticleVector::SetNumParticles(int num_vectors, bool keep_data)
251{
252 int old_nv = GetNumParticles();
253
254 if (num_vectors == old_nv)
255 {
256 return;
257 }
258
259 // If resizing larger...
260 if (num_vectors > old_nv)
261 {
262 // Increase capacity if needed
263 if (num_vectors*vdim > Vector::Capacity())
264 {
265 GrowSize(num_vectors, keep_data);
266 }
267
268 // Set larger new size
269 Vector::SetSize(num_vectors*vdim);
270
271 if (!keep_data) { return; }
272
274 {
275 // Shift entries for byNODES
276 for (int c = vdim-1; c > 0; c--)
277 {
278 for (int i = old_nv-1; i >= 0; i--)
279 {
280 Vector::operator[](i+c*num_vectors) = Vector::operator[](i+c*old_nv);
281 }
282 }
283
284 // Zero-out data now associated with new Vectors
285 for (int c = 0; c < vdim; c++)
286 {
287 for (int i = old_nv; i < num_vectors; i++)
288 {
289 Vector::operator[](i+c*num_vectors) = 0.0;
290 }
291 }
292 }
293 else // byVDIM
294 {
295 for (int i = old_nv*vdim; i < num_vectors*vdim; i++)
296 {
297 data[i] = 0.0;
298 }
299 }
300 }
301 else // Else just remove the trailing vector data
302 {
303 if (!keep_data) { Vector::SetSize(num_vectors*vdim); return; }
304 Array<int> rm_indices(old_nv-num_vectors);
305 for (int i = 0; i < rm_indices.Size(); i++)
306 {
307 rm_indices[i] = old_nv - rm_indices.Size() + i;
308 }
309 DeleteParticles(rm_indices);
310 }
311}
312
313} // namespace mfem
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Definition array.cpp:69
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
Definition array.hpp:184
int Size() const
Return the logical size of the array.
Definition array.hpp:166
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Definition array.hpp:912
Class used by MFEM to store pointers to host and/or device memory.
int Capacity() const
Return the size of the allocated memory.
bool UseDevice() const
Read the internal device flag.
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
void Delete()
Delete the owned pointers and reset the Memory object.
Type
Ordering methods:
Definition ordering.hpp:17
static void Reorder(Vector &v, int vdim, Type in_ord, Type out_ord)
Reorder Vector v from its current ordering in_ord to out_ord.
Definition ordering.cpp:38
ParticleVector carries vector data (of a given vector dimension) for an arbitrary number of particles...
Ordering::Type ordering
Ordering of Vector data in ParticleVector.
void SetValues(int i, const Vector &nvals)
Set particle i 's data to nvals .
real_t & operator()(int i, int comp)
Reference to particle i component comp value.
void GetValues(int i, Vector &nvals) const
Get a copy of particle i 's data.
int vdim
Vector dimension.
int GetNumParticles() const
Get the number of particle data in the ParticleVector.
void DeleteParticles(const Array< int > &indices)
Remove particle data at indices.
void SetNumParticles(int num_vectors, bool keep_data=true)
Set the number of particle Vector data to be held by the ParticleVector, keeping existing data.
void SetOrdering(Ordering::Type ordering_, bool keep_data=true)
Set the ordering of the particle Vector data in ParticleVector.
void GetComponents(int vd, Vector &comp)
Get a copy of component vd for all particle vector data.
void SetVDim(int vdim_, bool keep_data=true)
Set the vector dimension of the ParticleVector.
void GetValuesRef(int i, Vector &nref)
For GetOrdering == Ordering::byVDIM, set nref to refer to particle i 's data.
void SetComponents(int vd, const Vector &comp)
Set component vd values for all particle data to comp .
void GetComponentsRef(int vd, Vector &nref)
For GetOrdering == Ordering::byNODES, set nref to refer to component vd 's data.
void GrowSize(int min_num_vectors, bool keep_data)
Re-allocate + copy memory. See Array::GrowSize.
Vector data type.
Definition vector.hpp:82
Memory< real_t > data
Definition vector.hpp:85
real_t & operator[](int i)
Access Vector entries using [] for 0-based indexing.
Definition vector.hpp:304
void DeleteAt(const Array< int > &indices)
Definition vector.cpp:1260
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
int Capacity() const
Return the size of the currently allocated data array.
Definition vector.hpp:238
Vector & operator=(const real_t *v)
Copy Size() entries from v.
Definition vector.cpp:197
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
Definition vector.hpp:660
float real_t
Definition config.hpp:46
real_t p(const Vector &x, real_t t)