Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_ParticleIO.H
Go to the documentation of this file.
1#ifndef AMREX_PARTICLEIO_H
2#define AMREX_PARTICLEIO_H
3#include <AMReX_Config.H>
4
6#include <AMReX_VisMF.H>
7
8#include <iterator>
9
10namespace amrex {
11
12template <typename ParticleType, int NArrayReal, int NArrayInt,
13 template<class> class Allocator, class CellAssignor>
14void
15ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>
16::WriteParticleRealData (void* data, size_t size, std::ostream& os) const
17{
18 if (sizeof(typename ParticleType::RealType) == 4) {
19 writeFloatData((float*) data, size, os, ParticleRealDescriptor);
20 }
21 else if (sizeof(typename ParticleType::RealType) == 8) {
22 writeDoubleData((double*) data, size, os, ParticleRealDescriptor);
23 }
24}
25
26template <typename ParticleType, int NArrayReal, int NArrayInt,
27 template<class> class Allocator, class CellAssignor>
28void
30::ReadParticleRealData (void* data, size_t size, std::istream& is)
31{
32 if (sizeof(typename ParticleType::RealType) == 4) {
33 readFloatData((float*) data, size, is, ParticleRealDescriptor);
34 }
35 else if (sizeof(typename ParticleType::RealType) == 8) {
36 readDoubleData((double*) data, size, is, ParticleRealDescriptor);
37 }
38}
39
41 template <typename P>
43 int operator() (const P& p) const {
44 return p.id().is_valid();
45 }
46};
47
49template <typename ParticleType, int NArrayReal, int NArrayInt,
50 template<class> class Allocator, class CellAssignor>
51void
52ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>
53::Checkpoint (const std::string& dir,
54 const std::string& name, bool /*is_checkpoint*/,
55 const Vector<std::string>& real_comp_names,
56 const Vector<std::string>& int_comp_names) const
57{
58 Vector<int> write_real_comp;
59 Vector<std::string> tmp_real_comp_names;
60
61 int first_rcomp = ParticleType::is_soa_particle ? AMREX_SPACEDIM : 0;
62 for (int i = first_rcomp; i < NStructReal + NumRealComps(); ++i )
63 {
64 write_real_comp.push_back(1);
65 if (real_comp_names.empty())
66 {
67 tmp_real_comp_names.push_back(getDefaultCompNameReal<ParticleType>(i));
68 }
69 else
70 {
71 tmp_real_comp_names.push_back(real_comp_names[i-first_rcomp]);
72 }
73 }
74
75 Vector<int> write_int_comp;
76 Vector<std::string> tmp_int_comp_names;
77 for (int i = 0; i < NStructInt + NumIntComps(); ++i )
78 {
79 write_int_comp.push_back(1);
80 if (int_comp_names.empty())
81 {
82 tmp_int_comp_names.push_back(getDefaultCompNameInt<ParticleType>(i));
83 }
84 else
85 {
86 tmp_int_comp_names.push_back(int_comp_names[i]);
87 }
88 }
89
90 WriteBinaryParticleData(dir, name, write_real_comp, write_int_comp,
91 tmp_real_comp_names, tmp_int_comp_names,
92 FilterPositiveID{}, true);
93}
94
95template <typename ParticleType, int NArrayReal, int NArrayInt,
96 template<class> class Allocator, class CellAssignor>
97void
99::Checkpoint (const std::string& dir, const std::string& name,
100 const Vector<int>& write_real_comp,
101 const Vector<int>& write_int_comp,
102 const Vector<std::string>& real_comp_names,
103 const Vector<std::string>& int_comp_names) const
104{
105 WriteBinaryParticleData(dir, name, write_real_comp, write_int_comp,
106 real_comp_names, int_comp_names,
107 FilterPositiveID{}, true);
108}
109
111template <typename ParticleType, int NArrayReal, int NArrayInt,
112 template<class> class Allocator, class CellAssignor>
113void
115::WritePlotFile (const std::string& dir, const std::string& name) const
116{
117 Vector<int> write_real_comp;
118 Vector<std::string> real_comp_names;
119
120 int first_rcomp = ParticleType::is_soa_particle ? AMREX_SPACEDIM : 0;
121 for (int i = first_rcomp; i < NStructReal + NumRealComps(); ++i )
122 {
123 write_real_comp.push_back(1);
124 real_comp_names.push_back(getDefaultCompNameReal<ParticleType>(i));
125 }
126
127 Vector<int> write_int_comp;
128 Vector<std::string> int_comp_names;
129 for (int i = 0; i < NStructInt + NumIntComps(); ++i )
130 {
131 write_int_comp.push_back(1);
132 int_comp_names.push_back(getDefaultCompNameInt<ParticleType>(i));
133 }
134
135 WriteBinaryParticleData(dir, name, write_real_comp, write_int_comp,
136 real_comp_names, int_comp_names,
138}
139
141template <typename ParticleType, int NArrayReal, int NArrayInt,
142 template<class> class Allocator, class CellAssignor>
143void
145::WritePlotFile (const std::string& dir, const std::string& name,
146 const Vector<std::string>& real_comp_names,
147 const Vector<std::string>& int_comp_names) const
148{
149 if constexpr(ParticleType::is_soa_particle) {
150 AMREX_ALWAYS_ASSERT(real_comp_names.size() == NumRealComps() + NStructReal - AMREX_SPACEDIM); // pure SoA: skip positions
151 } else {
152 AMREX_ALWAYS_ASSERT(real_comp_names.size() == NumRealComps() + NStructReal);
153 }
154 AMREX_ASSERT( int_comp_names.size() == NStructInt + NumIntComps() );
155
156 Vector<int> write_real_comp;
157 int nrc = ParticleType::is_soa_particle ? NStructReal + NumRealComps() - AMREX_SPACEDIM : NStructReal + NumRealComps();
158 for (int i = 0; i < nrc; ++i) {
159 write_real_comp.push_back(1);
160 }
161
162 Vector<int> write_int_comp;
163 for (int i = 0; i < NStructInt + NumIntComps(); ++i) {
164 write_int_comp.push_back(1);
165 }
166
167 WriteBinaryParticleData(dir, name,
168 write_real_comp, write_int_comp,
169 real_comp_names, int_comp_names,
171}
172
174template <typename ParticleType, int NArrayReal, int NArrayInt,
175 template<class> class Allocator, class CellAssignor>
176void
178::WritePlotFile (const std::string& dir, const std::string& name,
179 const Vector<std::string>& real_comp_names) const
180{
181 if constexpr(ParticleType::is_soa_particle) {
182 AMREX_ALWAYS_ASSERT(real_comp_names.size() == NumRealComps() + NStructReal - AMREX_SPACEDIM); // pure SoA: skip positions
183 } else {
184 AMREX_ALWAYS_ASSERT(real_comp_names.size() == NumRealComps() + NStructReal);
185 }
186
187 Vector<int> write_real_comp;
188 int nrc = ParticleType::is_soa_particle ? NStructReal + NumRealComps() - AMREX_SPACEDIM : NStructReal + NumRealComps();
189 for (int i = 0; i < nrc; ++i) {
190 write_real_comp.push_back(1);
191 }
192
193 Vector<int> write_int_comp;
194 for (int i = 0; i < NStructInt + NumIntComps(); ++i) {
195 write_int_comp.push_back(1);
196 }
197
198 Vector<std::string> int_comp_names;
199 for (int i = 0; i < NStructInt + NumIntComps(); ++i )
200 {
201 int_comp_names.push_back(getDefaultCompNameInt<ParticleType>(i));
202 }
203
204 WriteBinaryParticleData(dir, name,
205 write_real_comp, write_int_comp,
206 real_comp_names, int_comp_names,
208}
209
211template <typename ParticleType, int NArrayReal, int NArrayInt,
212 template<class> class Allocator, class CellAssignor>
213void
215::WritePlotFile (const std::string& dir,
216 const std::string& name,
217 const Vector<int>& write_real_comp,
218 const Vector<int>& write_int_comp) const
219{
220
221 if constexpr(ParticleType::is_soa_particle) {
222 AMREX_ALWAYS_ASSERT(write_real_comp.size() == NumRealComps() + NStructReal - AMREX_SPACEDIM); // pure SoA: skip positions
223 } else {
224 AMREX_ALWAYS_ASSERT(write_real_comp.size() == NumRealComps() + NStructReal);
225 }
226 AMREX_ASSERT(write_int_comp.size() == NStructInt + NumIntComps() );
227
228 Vector<std::string> real_comp_names;
229 int first_rcomp = ParticleType::is_soa_particle ? AMREX_SPACEDIM : 0;
230 for (int i = first_rcomp; i < NStructReal + NumRealComps(); ++i )
231 {
232 real_comp_names.push_back(getDefaultCompNameReal<ParticleType>(i));
233 }
234
235 Vector<std::string> int_comp_names;
236 for (int i = 0; i < NStructInt + NumIntComps(); ++i )
237 {
238 int_comp_names.push_back(getDefaultCompNameInt<ParticleType>(i));
239 }
240
241 WriteBinaryParticleData(dir, name, write_real_comp, write_int_comp,
242 real_comp_names, int_comp_names,
244}
245
247template <typename ParticleType, int NArrayReal, int NArrayInt,
248 template<class> class Allocator, class CellAssignor>
249void
251WritePlotFile (const std::string& dir, const std::string& name,
252 const Vector<int>& write_real_comp,
253 const Vector<int>& write_int_comp,
254 const Vector<std::string>& real_comp_names,
255 const Vector<std::string>& int_comp_names) const
256{
257 BL_PROFILE("ParticleContainer::WritePlotFile()");
258
259 WriteBinaryParticleData(dir, name,
260 write_real_comp, write_int_comp,
261 real_comp_names, int_comp_names,
263}
264
266template <typename ParticleType, int NArrayReal, int NArrayInt,
267 template<class> class Allocator, class CellAssignor>
268template <class F>
269void
271::WritePlotFile (const std::string& dir, const std::string& name, F const& f) const
272{
273 Vector<int> write_real_comp;
274 Vector<std::string> real_comp_names;
275
276 int first_rcomp = ParticleType::is_soa_particle ? AMREX_SPACEDIM : 0;
277 for (int i = first_rcomp; i < NStructReal + NumRealComps(); ++i )
278 {
279 write_real_comp.push_back(1);
280 real_comp_names.push_back(getDefaultCompNameReal<ParticleType>(i));
281 }
282
283 Vector<int> write_int_comp;
284 Vector<std::string> int_comp_names;
285 for (int i = 0; i < NStructInt + NumIntComps(); ++i )
286 {
287 write_int_comp.push_back(1);
288 int_comp_names.push_back(getDefaultCompNameInt<ParticleType>(i));
289 }
290
291 WriteBinaryParticleData(dir, name, write_real_comp, write_int_comp,
292 real_comp_names, int_comp_names, f);
293}
294
296template <typename ParticleType, int NArrayReal, int NArrayInt,
297 template<class> class Allocator, class CellAssignor>
298template <class F>
299void
301::WritePlotFile (const std::string& dir, const std::string& name,
302 const Vector<std::string>& real_comp_names,
303 const Vector<std::string>& int_comp_names, F const& f) const
304{
305 if constexpr(ParticleType::is_soa_particle) {
306 AMREX_ALWAYS_ASSERT(real_comp_names.size() == NumRealComps() + NStructReal - AMREX_SPACEDIM); // pure SoA: skip positions
307 } else {
308 AMREX_ALWAYS_ASSERT(real_comp_names.size() == NumRealComps() + NStructReal);
309 }
310 AMREX_ASSERT( int_comp_names.size() == NStructInt + NumIntComps() );
311
312 Vector<int> write_real_comp;
313 int nrc = ParticleType::is_soa_particle ? NStructReal + NumRealComps() - AMREX_SPACEDIM : NStructReal + NumRealComps();
314 for (int i = 0; i < nrc; ++i) {
315 write_real_comp.push_back(1);
316 }
317
318 Vector<int> write_int_comp;
319 for (int i = 0; i < NStructInt + NumIntComps(); ++i) {
320 write_int_comp.push_back(1);
321 }
322
323 WriteBinaryParticleData(dir, name,
324 write_real_comp, write_int_comp,
325 real_comp_names, int_comp_names, f);
326}
327
329template <typename ParticleType, int NArrayReal, int NArrayInt,
330 template<class> class Allocator, class CellAssignor>
331template <class F>
332void
334::WritePlotFile (const std::string& dir, const std::string& name,
335 const Vector<std::string>& real_comp_names, F const& f) const
336{
337 if constexpr(ParticleType::is_soa_particle) {
338 AMREX_ALWAYS_ASSERT(real_comp_names.size() == NumRealComps() + NStructReal - AMREX_SPACEDIM); // pure SoA: skip positions
339 } else {
340 AMREX_ALWAYS_ASSERT(real_comp_names.size() == NumRealComps() + NStructReal);
341 }
342
343 Vector<int> write_real_comp;
344 int nrc = ParticleType::is_soa_particle ? NStructReal + NumRealComps() - AMREX_SPACEDIM : NStructReal + NumRealComps();
345 for (int i = 0; i < nrc; ++i) {
346 write_real_comp.push_back(1);
347 }
348
349 Vector<int> write_int_comp;
350 for (int i = 0; i < NStructInt + NumIntComps(); ++i) {
351 write_int_comp.push_back(1);
352 }
353
354 Vector<std::string> int_comp_names;
355 for (int i = 0; i < NStructInt + NumIntComps(); ++i )
356 {
357 int_comp_names.push_back(getDefaultCompNameInt<ParticleType>(i));
358 }
359
360 WriteBinaryParticleData(dir, name,
361 write_real_comp, write_int_comp,
362 real_comp_names, int_comp_names, f);
363}
364
366template <typename ParticleType, int NArrayReal, int NArrayInt,
367 template<class> class Allocator, class CellAssignor>
368template <class F>
369void
371::WritePlotFile (const std::string& dir,
372 const std::string& name,
373 const Vector<int>& write_real_comp,
374 const Vector<int>& write_int_comp, F const& f) const
375{
376 if constexpr(ParticleType::is_soa_particle) {
377 AMREX_ALWAYS_ASSERT(write_real_comp.size() == NumRealComps() + NStructReal - AMREX_SPACEDIM); // pure SoA: skip positions
378 } else {
379 AMREX_ALWAYS_ASSERT(write_real_comp.size() == NumRealComps() + NStructReal);
380 }
381 AMREX_ASSERT(write_int_comp.size() == NStructInt + NumIntComps() );
382
383 Vector<std::string> real_comp_names;
384 int first_rcomp = ParticleType::is_soa_particle ? AMREX_SPACEDIM : 0;
385 for (int i = first_rcomp; i < NStructReal + NumRealComps(); ++i )
386 {
387 real_comp_names.push_back(getDefaultCompNameReal<ParticleType>(i));
388 }
389
390 Vector<std::string> int_comp_names;
391 for (int i = 0; i < NStructInt + NumIntComps(); ++i )
392 {
393 int_comp_names.push_back(getDefaultCompNameInt<ParticleType>(i));
394 }
395
396 WriteBinaryParticleData(dir, name, write_real_comp, write_int_comp,
397 real_comp_names, int_comp_names, f);
398}
399
401template <typename ParticleType, int NArrayReal, int NArrayInt,
402 template<class> class Allocator, class CellAssignor>
403template <class F>
404void
406WritePlotFile (const std::string& dir, const std::string& name,
407 const Vector<int>& write_real_comp,
408 const Vector<int>& write_int_comp,
409 const Vector<std::string>& real_comp_names,
410 const Vector<std::string>& int_comp_names,
411 F const& f) const
412{
413 BL_PROFILE("ParticleContainer::WritePlotFile()");
414
415 WriteBinaryParticleData(dir, name,
416 write_real_comp, write_int_comp,
417 real_comp_names, int_comp_names, f);
418}
419
420template <typename ParticleType, int NArrayReal, int NArrayInt,
421 template<class> class Allocator, class CellAssignor>
422template <class F>
423void
425::WriteBinaryParticleData (const std::string& dir, const std::string& name,
426 const Vector<int>& write_real_comp,
427 const Vector<int>& write_int_comp,
428 const Vector<std::string>& real_comp_names,
429 const Vector<std::string>& int_comp_names,
430 F const& f, bool is_checkpoint) const
431{
432 if (AsyncOut::UseAsyncOut()) {
433 WriteBinaryParticleDataAsync(*this, dir, name,
434 write_real_comp, write_int_comp,
435 real_comp_names, int_comp_names, is_checkpoint);
436 } else
437 {
438 WriteBinaryParticleDataSync(*this, dir, name,
439 write_real_comp, write_int_comp,
440 real_comp_names, int_comp_names,
441 f, is_checkpoint);
442 }
443}
444
445template <typename ParticleType, int NArrayReal, int NArrayInt,
446 template<class> class Allocator, class CellAssignor>
447void
450{
451 if( ! usePrePost) {
452 return;
453 }
454
455 BL_PROFILE("ParticleContainer::CheckpointPre()");
456
457 const int IOProcNumber = ParallelDescriptor::IOProcessorNumber();
458 Long nparticles = 0;
459 Long maxnextid = ParticleType::NextID();
460
461 for (int lev = 0; lev < std::ssize(m_particles); lev++) {
462 const auto& pmap = m_particles[lev];
463 for (const auto& kv : pmap) {
464 const auto& aos = kv.second.GetArrayOfStructs();
465 for (int k = 0; k < aos.numParticles(); ++k) {
466 const ParticleType& p = aos[k];
467 if (p.id().is_valid()) {
468 //
469 // Only count (and checkpoint) valid particles.
470 //
471 nparticles++;
472 }
473 }
474 }
475 }
476 ParallelDescriptor::ReduceLongSum(nparticles, IOProcNumber);
477
478 ParticleType::NextID(maxnextid);
479 ParallelDescriptor::ReduceLongMax(maxnextid, IOProcNumber);
480
481 nparticlesPrePost = nparticles;
482 maxnextidPrePost = maxnextid;
483
484 nParticlesAtLevelPrePost.clear();
485 nParticlesAtLevelPrePost.resize(finestLevel() + 1, 0);
486 for(int lev(0); lev <= finestLevel(); ++lev) {
487 nParticlesAtLevelPrePost[lev] = NumberOfParticlesAtLevel(lev);
488 }
489
490 whichPrePost.clear();
491 whichPrePost.resize(finestLevel() + 1);
492 countPrePost.clear();
493 countPrePost.resize(finestLevel() + 1);
494 wherePrePost.clear();
495 wherePrePost.resize(finestLevel() + 1);
496
497 filePrefixPrePost.clear();
498 filePrefixPrePost.resize(finestLevel() + 1);
499}
500
501
502template <typename ParticleType, int NArrayReal, int NArrayInt,
503 template<class> class Allocator, class CellAssignor>
504void
507{
508 if( ! usePrePost) {
509 return;
510 }
511
512 BL_PROFILE("ParticleContainer::CheckpointPost()");
513
514 const int IOProcNumber = ParallelDescriptor::IOProcessorNumber();
515 std::ofstream HdrFile;
516 HdrFile.open(HdrFileNamePrePost.c_str(), std::ios::out | std::ios::app);
517
518 for(int lev(0); lev <= finestLevel(); ++lev) {
519 ParallelDescriptor::ReduceIntSum (whichPrePost[lev].dataPtr(), whichPrePost[lev].size(), IOProcNumber);
520 ParallelDescriptor::ReduceIntSum (countPrePost[lev].dataPtr(), countPrePost[lev].size(), IOProcNumber);
521 ParallelDescriptor::ReduceLongSum(wherePrePost[lev].dataPtr(), wherePrePost[lev].size(), IOProcNumber);
522
523
525 for(int j(0); j < whichPrePost[lev].size(); ++j) {
526 HdrFile << whichPrePost[lev][j] << ' ' << countPrePost[lev][j] << ' ' << wherePrePost[lev][j] << '\n';
527 }
528
529 const bool gotsome = (nParticlesAtLevelPrePost[lev] > 0);
530 if(gotsome && doUnlink) {
531// BL_PROFILE_VAR("PC<NNNN>::Checkpoint:unlink", unlink_post);
532 // Unlink any zero-length data files.
533 Vector<Long> cnt(nOutFilesPrePost,0);
534
535 for(int i(0), N = countPrePost[lev].size(); i < N; ++i) {
536 cnt[whichPrePost[lev][i]] += countPrePost[lev][i];
537 }
538
539 for(int i = 0; i < std::ssize(cnt); ++i) {
540 if(cnt[i] == 0) {
541 std::string FullFileName = NFilesIter::FileName(i, filePrefixPrePost[lev]);
542 FileSystem::Remove(FullFileName);
543 }
544 }
545 }
546 }
547 }
548
550 HdrFile.flush();
551 HdrFile.close();
552 if( ! HdrFile.good()) {
553 amrex::Abort("ParticleContainer::CheckpointPost(): problem writing HdrFile");
554 }
555 }
556}
557
558template <typename ParticleType, int NArrayReal, int NArrayInt,
559 template<class> class Allocator, class CellAssignor>
560void
563{
564 CheckpointPre();
565}
566
567
568template <typename ParticleType, int NArrayReal, int NArrayInt,
569 template<class> class Allocator, class CellAssignor>
570void
573{
574 CheckpointPost();
575}
576
577
578template <typename ParticleType, int NArrayReal, int NArrayInt,
579 template<class> class Allocator, class CellAssignor>
580void
582::WriteParticles (int lev, std::ofstream& ofs, int fnum,
583 Vector<int>& which, Vector<int>& count, Vector<Long>& where,
584 const Vector<int>& write_real_comp,
585 const Vector<int>& write_int_comp,
586 const Vector<std::map<std::pair<int, int>, FlagsVector>>& particle_io_flags,
587 bool is_checkpoint) const
588{
589 BL_PROFILE("ParticleContainer::WriteParticles()");
590
591 // For a each grid, the tiles it contains
592 std::map<int, Vector<int> > tile_map;
593
594 for (const auto& kv : m_particles[lev])
595 {
596 const int grid = kv.first.first;
597 const int tile = kv.first.second;
598 tile_map[grid].push_back(tile);
599 const auto& pflags = particle_io_flags[lev].at(kv.first);
600
601 // Only write out valid particles.
602 count[grid] += particle_detail::countFlags(pflags);
603 }
604
605 MFInfo info;
606 info.SetAlloc(false);
607 MultiFab state(ParticleBoxArray(lev), ParticleDistributionMap(lev), 1,0,info);
608
609 for (MFIter mfi(state); mfi.isValid(); ++mfi)
610 {
611 const int grid = mfi.index();
612
613 which[grid] = fnum;
614 where[grid] = VisMF::FileOffset(ofs);
615
616 if (count[grid] <= 0) { continue; }
617
618 Vector<int> istuff;
620 particle_detail::packIOData(istuff, rstuff, *this, lev, grid,
621 write_real_comp, write_int_comp,
622 particle_io_flags, tile_map[grid], count[grid], is_checkpoint);
623
624 writeIntData(istuff.dataPtr(), istuff.size(), ofs);
626 ofs.flush(); // Some systems require this flush() (probably due to a bug)
627 }
628
629 WriteParticleRealData(rstuff.dataPtr(), rstuff.size(), ofs);
631 ofs.flush(); // Some systems require this flush() (probably due to a bug)
632 }
633 }
634}
635
636
637template <typename ParticleType, int NArrayReal, int NArrayInt,
638 template<class> class Allocator, class CellAssignor>
639void
641::Restart (const std::string& dir, const std::string& file, bool /*is_checkpoint*/)
642{
643 Restart(dir, file);
644}
645
646template <typename ParticleType, int NArrayReal, int NArrayInt,
647 template<class> class Allocator, class CellAssignor>
648void
650::Restart (const std::string& dir, const std::string& file)
651{
652 BL_PROFILE("ParticleContainer::Restart()");
653 AMREX_ASSERT(!dir.empty());
654 AMREX_ASSERT(!file.empty());
655
656 const auto strttime = amrex::second();
657
658 int DATA_Digits_Read(5);
659 ParmParse pp("particles");
660 pp.query("datadigits_read",DATA_Digits_Read);
661
662 std::string fullname = dir;
663 if (!fullname.empty() && fullname[fullname.size()-1] != '/') {
664 fullname += '/';
665 }
666 fullname += file;
667 std::string HdrFileName = fullname;
668 if (!HdrFileName.empty() && HdrFileName[HdrFileName.size()-1] != '/') {
669 HdrFileName += '/';
670 }
671 HdrFileName += "Header";
672
673 Vector<char> fileCharPtr;
674 ParallelDescriptor::ReadAndBcastFile(HdrFileName, fileCharPtr);
675 std::string fileCharPtrString(fileCharPtr.dataPtr());
676 std::istringstream HdrFile(fileCharPtrString, std::istringstream::in);
677
678 std::string version;
679 HdrFile >> version;
680 AMREX_ASSERT(!version.empty());
681
682 // What do our version strings mean?
683 // "Version_One_Dot_Zero" -- hard-wired to write out in double precision.
684 // "Version_One_Dot_One" -- can write out either as either single or double precision.
685 // Appended to the latter version string are either "_single" or "_double" to
686 // indicate how the particles were written.
687 // "Version_Two_Dot_Zero" -- this is the AMReX particle file format
688 // "Version_Two_Dot_One" -- expanded particle ids to allow for 2**39-1 per proc
689 std::string how;
690 bool convert_ids = false;
691 if (version.find("Version_Two_Dot_One") != std::string::npos) {
692 convert_ids = true;
693 }
694 if (version.find("Version_One_Dot_Zero") != std::string::npos) {
695 how = "double";
696 }
697 else if (version.find("Version_One_Dot_One") != std::string::npos ||
698 version.find("Version_Two_Dot_Zero") != std::string::npos ||
699 version.find("Version_Two_Dot_One") != std::string::npos) {
700 if (version.find("_single") != std::string::npos) {
701 how = "single";
702 }
703 else if (version.find("_double") != std::string::npos) {
704 how = "double";
705 }
706 else {
707 std::string msg("ParticleContainer::Restart(): bad version string: ");
708 msg += version;
709 amrex::Error(version.c_str());
710 }
711 }
712 else {
713 std::string msg("ParticleContainer::Restart(): unknown version string: ");
714 msg += version;
715 amrex::Abort(msg.c_str());
716 }
717
718 int dm;
719 HdrFile >> dm;
720 if (dm != AMREX_SPACEDIM) {
721 amrex::Abort("ParticleContainer::Restart(): dm != AMREX_SPACEDIM");
722 }
723
724 int nr;
725 HdrFile >> nr;
726 int nrc = ParticleType::is_soa_particle ? NStructReal + NumRealComps() - AMREX_SPACEDIM : NStructReal + NumRealComps();
727 if (nr != nrc) {
728 amrex::Abort("ParticleContainer::Restart(): nr not the expected value");
729 }
730
731 std::string comp_name;
732 for (int i = 0; i < nr; ++i) {
733 HdrFile >> comp_name;
734 }
735
736 int ni;
737 HdrFile >> ni;
738 if (ni != NStructInt + NumIntComps()) {
739 amrex::Abort("ParticleContainer::Restart(): ni != NStructInt");
740 }
741
742 for (int i = 0; i < ni; ++i) {
743 HdrFile >> comp_name;
744 }
745
746 bool checkpoint;
747 HdrFile >> checkpoint;
748
749 Long nparticles;
750 HdrFile >> nparticles;
751 AMREX_ASSERT(nparticles >= 0);
752
753 Long maxnextid;
754 HdrFile >> maxnextid;
755 AMREX_ASSERT(maxnextid > 0);
756 ParticleType::NextID(maxnextid);
757
758 int finest_level_in_file;
759 HdrFile >> finest_level_in_file;
760 AMREX_ASSERT(finest_level_in_file >= 0);
761
762 // Determine whether this is a dual-grid restart or not.
763 // Size the vectors to cover both the levels present in the checkpoint
764 // file and the levels present in the current container, since the
765 // loops below iterate up to finestLevel()
766 int const max_level = std::max(finest_level_in_file, finestLevel());
767 Vector<DistributionMapping> old_dms(max_level + 1);
768 Vector<BoxArray> old_bas(max_level + 1);
769 Vector<BoxArray> particle_box_arrays(max_level + 1);
770 bool dual_grid = false;
771
772 bool have_pheaders = false;
773 for (int lev = 0; lev <= finest_level_in_file; lev++)
774 {
775 std::string phdr_name = fullname;
776 phdr_name += "/Level_";
777 phdr_name = amrex::Concatenate(phdr_name, lev, 1);
778 phdr_name += "/Particle_H";
779
780 if (amrex::FileExists(phdr_name)) {
781 have_pheaders = true;
782 break;
783 }
784 }
785
786 if (have_pheaders)
787 {
788 for (int lev = 0; lev <= finestLevel(); lev++)
789 {
790 old_dms[lev] = ParticleDistributionMap(lev);
791 old_bas[lev] = ParticleBoxArray(lev);
792 std::string phdr_name = fullname;
793 phdr_name += "/Level_";
794 phdr_name = amrex::Concatenate(phdr_name, lev, 1);
795 phdr_name += "/Particle_H";
796
797 if (! amrex::FileExists(phdr_name)) {
798 // No particles were checkpointed at this level. Dual-grid
799 // restart will use a single-box domain BoxArray as the
800 // temporary layout for this level, so detect that mismatch
801 // here as well.
802 particle_box_arrays[lev] = BoxArray(Geom(lev).Domain());
803 if (! particle_box_arrays[lev].CellEqual(ParticleBoxArray(lev))) {
804 dual_grid = true;
805 }
806 continue;
807 }
808
809 Vector<char> phdr_chars;
810 ParallelDescriptor::ReadAndBcastFile(phdr_name, phdr_chars);
811 std::string phdr_string(phdr_chars.dataPtr());
812 std::istringstream phdr_file(phdr_string, std::istringstream::in);
813
814 particle_box_arrays[lev].readFrom(phdr_file);
815 if (! particle_box_arrays[lev].CellEqual(ParticleBoxArray(lev))) { dual_grid = true; }
816 }
817 } else // if no particle box array information exists in the file, we assume a single grid restart
819 dual_grid = false;
820 }
821
822 if (dual_grid) {
823 for (int lev = 0; lev <= finestLevel(); lev++) {
824 // this can happen if there are no particles at a given level in the checkpoint
825 if (particle_box_arrays[lev].empty()) {
826 particle_box_arrays[lev] = BoxArray(Geom(lev).Domain());
827 }
828 SetParticleBoxArray(lev, particle_box_arrays[lev]);
829 DistributionMapping pdm(particle_box_arrays[lev]);
830 SetParticleDistributionMap(lev, pdm);
831 }
832 }
833
834 Vector<int> ngrids(finest_level_in_file+1);
835 for (int lev = 0; lev <= finest_level_in_file; lev++) {
836 HdrFile >> ngrids[lev];
837 AMREX_ASSERT(ngrids[lev] > 0);
838 }
839
840 resizeData();
841
842 if (finest_level_in_file > finestLevel()) {
843 m_particles.resize(finest_level_in_file+1);
844 }
846 for (int lev = 0; lev <= finest_level_in_file; lev++) {
847 Vector<int> which(ngrids[lev]);
848 Vector<int> count(ngrids[lev]);
849 Vector<Long> where(ngrids[lev]);
850 for (int i = 0; i < ngrids[lev]; i++) {
851 HdrFile >> which[i] >> count[i] >> where[i];
852 }
854 Vector<int> grids_to_read;
855 if (lev <= finestLevel()) {
856 for (MFIter mfi(*m_dummy_mf[lev]); mfi.isValid(); ++mfi) {
857 grids_to_read.push_back(mfi.index());
858 }
859 } else {
860
861 // we lost a level on restart. we still need to read in particles
862 // on finer levels, and put them in the right place via Redistribute()
863
864 const int rank = ParallelDescriptor::MyProc();
865 const int NReaders = MaxReaders();
866 if (rank >= NReaders) { continue; }
868 const int Navg = ngrids[lev] / NReaders;
869 const int Nleft = ngrids[lev] - Navg * NReaders;
870
871 int lo, hi;
872 if (rank < Nleft) {
873 lo = rank*(Navg + 1);
874 hi = lo + Navg + 1;
875 }
876 else {
877 lo = rank * Navg + Nleft;
878 hi = lo + Navg;
879 }
880
881 for (int i = lo; i < hi; ++i) {
882 grids_to_read.push_back(i);
883 }
884 }
885
886 for(int grid : grids_to_read) {
887 if (count[grid] <= 0) { continue; }
888
889 // The file names in the header file are relative.
890 std::string name = fullname;
891
892 if (!name.empty() && name[name.size()-1] != '/') {
893 name += '/';
894 }
896 name += "Level_";
897 name += amrex::Concatenate("", lev, 1);
898 name += '/';
899 name += DataPrefix();
900 name += amrex::Concatenate("", which[grid], DATA_Digits_Read);
901
902 std::ifstream ParticleFile;
903
904 ParticleFile.open(name.c_str(), std::ios::in | std::ios::binary);
905
906 if (!ParticleFile.good()) {
908 }
909
910 ParticleFile.seekg(where[grid], std::ios::beg);
911
912 // Use if constexpr to avoid instantiating the mis-matched
913 // type case and triggering the static_assert on the
914 // underlying copy calls
915 if (how == "single") {
916 if constexpr (std::is_same_v<ParticleReal, float>) {
917 ReadParticles<float>(count[grid], grid, lev, ParticleFile, finest_level_in_file, convert_ids);
918 } else {
919 amrex::Error("File contains single-precision data, while AMReX is compiled with ParticleReal==double");
920 }
921 }
922 else if (how == "double") {
923 if constexpr (std::is_same_v<ParticleReal, double>) {
924 ReadParticles<double>(count[grid], grid, lev, ParticleFile, finest_level_in_file, convert_ids);
925 } else {
926 amrex::Error("File contains double-precision data, while AMReX is compiled with ParticleReal==float");
927 }
928 }
929 else {
930 std::string msg("ParticleContainer::Restart(): bad parameter: ");
931 msg += how;
932 amrex::Error(msg.c_str());
933 }
934
935 ParticleFile.close();
937 if (!ParticleFile.good()) {
938 amrex::Abort("ParticleContainer::Restart(): problem reading particles");
939 }
940 }
941 }
942
943 if (dual_grid) {
944 for (int lev = 0; lev <= finestLevel(); lev++) {
945 SetParticleBoxArray(lev, old_bas[lev]);
946 SetParticleDistributionMap(lev, old_dms[lev]);
947 }
948 }
949
950 Redistribute();
951
952 AMREX_ASSERT(OK());
953
954 if (m_verbose > 1) {
955 auto stoptime = amrex::second() - strttime;
957 amrex::Print() << "ParticleContainer::Restart() time: " << stoptime << '\n';
958 }
959}
960
961// Read a batch of particles from the checkpoint file
962template <typename ParticleType, int NArrayReal, int NArrayInt,
963 template<class> class Allocator, class CellAssignor>
964template <class RTYPE>
965void
966ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>
967::ReadParticles (int cnt, int grd, int lev, std::ifstream& ifs,
968 int finest_level_in_file, bool convert_ids)
969{
970 BL_PROFILE("ParticleContainer::ReadParticles()");
971 AMREX_ASSERT(cnt > 0);
972 AMREX_ASSERT(lev < std::ssize(m_particles));
973
974 // First read in the integer data in binary. We do not store
975 // the m_lev and m_grid data on disk. We can easily recreate
976 // that given the structure of the checkpoint file.
977 const int iChunkSize = 2 + NStructInt + NumIntComps();
978 Vector<int> istuff(std::size_t(cnt)*iChunkSize);
979 readIntData(istuff.dataPtr(), istuff.size(), ifs, FPC::NativeIntDescriptor());
980
981 // Then the real data in binary.
982 const int rChunkSize = ParticleType::is_soa_particle ? NStructReal + NumRealComps() : AMREX_SPACEDIM + NStructReal + NumRealComps();
983 Vector<RTYPE> rstuff(std::size_t(cnt)*rChunkSize);
984 ReadParticleRealData(rstuff.dataPtr(), rstuff.size(), ifs);
985
986 // Now reassemble the particles.
987 int* iptr = istuff.dataPtr();
988 RTYPE* rptr = rstuff.dataPtr();
989
991 ParticleLocData pld;
992
994 host_particles.reserve(15);
995 host_particles.resize(finest_level_in_file+1);
996
998 std::vector<Gpu::HostVector<RTYPE> > > > host_real_attribs;
999 host_real_attribs.reserve(15);
1000 host_real_attribs.resize(finest_level_in_file+1);
1001
1003 std::vector<Gpu::HostVector<int> > > > host_int_attribs;
1004 host_int_attribs.reserve(15);
1005 host_int_attribs.resize(finest_level_in_file+1);
1006
1008 host_idcpu.reserve(15);
1009 host_idcpu.resize(finest_level_in_file+1);
1011 for (int i = 0; i < cnt; i++) {
1012 // note: for pure SoA particle layouts, we do write the id, cpu and positions as a struct
1013 // for backwards compatibility with readers
1014 if (convert_ids) {
1015 std::int32_t xi, yi;
1016 std::uint32_t xu, yu;
1017 xi = iptr[0];
1018 yi = iptr[1];
1019 std::memcpy(&xu, &xi, sizeof(xi));
1020 std::memcpy(&yu, &yi, sizeof(yi));
1021 ptemp.m_idcpu = ((std::uint64_t)xu) << 32 | yu;
1022 } else {
1023 ptemp.id() = iptr[0];
1024 ptemp.cpu() = iptr[1];
1025 }
1026 iptr += 2;
1027
1028 for (int j = 0; j < NStructInt; j++)
1029 {
1030 ptemp.idata(j) = *iptr;
1031 ++iptr;
1032 }
1033
1034 AMREX_ASSERT(ptemp.id().is_valid());
1035
1036 AMREX_D_TERM(ptemp.pos(0) = ParticleReal(rptr[0]);,
1037 ptemp.pos(1) = ParticleReal(rptr[1]);,
1038 ptemp.pos(2) = ParticleReal(rptr[2]););
1039
1040 rptr += AMREX_SPACEDIM;
1041
1042 for (int j = 0; j < NStructReal; j++)
1043 {
1044 ptemp.rdata(j) = ParticleReal(*rptr);
1045 ++rptr;
1046 }
1047
1048 locateParticle(ptemp, pld, 0, finestLevel(), 0);
1049
1050 std::pair<int, int> ind(grd, pld.m_tile);
1051
1052 host_real_attribs[lev][ind].resize(NumRealComps());
1053 host_int_attribs[lev][ind].resize(NumIntComps());
1054
1055 // add the struct
1056 if constexpr(!ParticleType::is_soa_particle)
1057 {
1058 host_particles[lev][ind].push_back(ptemp);
1059
1060 // add the real...
1061 for (int icomp = 0; icomp < NumRealComps(); icomp++) {
1062 host_real_attribs[lev][ind][icomp].push_back(*rptr);
1063 ++rptr;
1064 }
1065
1066 // ... and int array data
1067 for (int icomp = 0; icomp < NumIntComps(); icomp++) {
1068 host_int_attribs[lev][ind][icomp].push_back(*iptr);
1069 ++iptr;
1070 }
1071 } else {
1072 host_particles[lev][ind];
1073
1074 for (int j = 0; j < AMREX_SPACEDIM; j++) {
1075 host_real_attribs[lev][ind][j].push_back(ptemp.pos(j));
1076 }
1077
1078 host_idcpu[lev][ind].push_back(ptemp.m_idcpu);
1079
1080 // read all other SoA
1081 // add the real...
1082 for (int icomp = AMREX_SPACEDIM; icomp < NumRealComps(); icomp++) {
1083 host_real_attribs[lev][ind][icomp].push_back(*rptr);
1084 ++rptr;
1085 }
1086
1087 // ... and int array data
1088 for (int icomp = 0; icomp < NumIntComps(); icomp++) {
1089 host_int_attribs[lev][ind][icomp].push_back(*iptr);
1090 ++iptr;
1091 }
1092 }
1093 }
1094
1095 for (int host_lev = 0; host_lev < std::ssize(host_particles); ++host_lev)
1096 {
1097 for (auto& kv : host_particles[host_lev]) {
1098 auto grid = kv.first.first;
1099 auto tile = kv.first.second;
1100 const auto& src_tile = kv.second;
1101
1102 auto& dst_tile = DefineAndReturnParticleTile(host_lev, grid, tile);
1103 auto old_size = dst_tile.size();
1104 auto new_size = old_size;
1105 if constexpr(!ParticleType::is_soa_particle)
1106 {
1107 new_size += src_tile.size();
1108 } else {
1109 amrex::ignore_unused(src_tile);
1110 new_size += host_real_attribs[host_lev][std::make_pair(grid,tile)][0].size();
1111 }
1112 dst_tile.resize(new_size);
1113
1114 if constexpr(!ParticleType::is_soa_particle)
1115 {
1116 Gpu::copyAsync(Gpu::hostToDevice, src_tile.begin(), src_tile.end(),
1117 dst_tile.GetArrayOfStructs().begin() + old_size);
1118 } else {
1120 host_idcpu[host_lev][std::make_pair(grid,tile)].begin(),
1121 host_idcpu[host_lev][std::make_pair(grid,tile)].end(),
1122 dst_tile.GetStructOfArrays().GetIdCPUData().begin() + old_size);
1123 }
1124
1125 for (int i = 0; i < NumRealComps(); ++i) { // NOLINT(readability-misleading-indentation)
1127 host_real_attribs[host_lev][std::make_pair(grid,tile)][i].begin(),
1128 host_real_attribs[host_lev][std::make_pair(grid,tile)][i].end(),
1129 dst_tile.GetStructOfArrays().GetRealData(i).begin() + old_size);
1130 }
1131
1132 for (int i = 0; i < NumIntComps(); ++i) {
1134 host_int_attribs[host_lev][std::make_pair(grid,tile)][i].begin(),
1135 host_int_attribs[host_lev][std::make_pair(grid,tile)][i].end(),
1136 dst_tile.GetStructOfArrays().GetIntData(i).begin() + old_size);
1137 }
1138 }
1139 }
1140
1142}
1143
1144template <typename ParticleType, int NArrayReal, int NArrayInt,
1145 template<class> class Allocator, class CellAssignor>
1146void
1147ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>
1148::WriteAsciiFile (const std::string& filename)
1149{
1150 BL_PROFILE("ParticleContainer::WriteAsciiFile()");
1151 AMREX_ASSERT(!filename.empty());
1152
1153 const auto strttime = amrex::second();
1154 //
1155 // Count # of valid particles.
1156 //
1157 Long nparticles = 0;
1158
1159 for (int lev = 0; lev < std::ssize(m_particles); lev++) {
1160 auto& pmap = m_particles[lev];
1161 for (const auto& kv : pmap) {
1162 const auto& aos = kv.second.GetArrayOfStructs();
1163 auto np = aos.numParticles();
1164 Gpu::HostVector<ParticleType> host_aos(np);
1165 Gpu::copy(Gpu::deviceToHost, aos.begin(), aos.begin() + np, host_aos.begin());
1166 for (int k = 0; k < np; ++k) {
1167 const ParticleType& p = host_aos[k];
1168 if (p.id().is_valid()) {
1169 //
1170 // Only count (and checkpoint) valid particles.
1171 //
1172 nparticles++;
1173 }
1174 }
1175 }
1176 }
1177
1178 //
1179 // And send count to I/O processor.
1180 //
1182
1184 {
1185 //
1186 // Have I/O processor open file and write out particle metadata.
1187 //
1188 std::ofstream File;
1189
1190 File.open(filename.c_str(), std::ios::out|std::ios::trunc);
1191
1192 if (!File.good()) {
1193 amrex::FileOpenFailed(filename);
1194 }
1195
1196 File << nparticles << '\n';
1197 File << NStructReal << '\n';
1198 File << NStructInt << '\n';
1199 File << NumRealComps() << '\n';
1200 File << NumIntComps() << '\n';
1201
1202 File.flush();
1203
1204 File.close();
1205
1206 if (!File.good()) {
1207 amrex::Abort("ParticleContainer::WriteAsciiFile(): problem writing file");
1208 }
1209 }
1210
1212
1213 const int MyProc = ParallelDescriptor::MyProc();
1214
1215 for (int proc = 0; proc < ParallelDescriptor::NProcs(); proc++)
1216 {
1217 if (MyProc == proc)
1218 {
1219 //
1220 // Each CPU opens the file for appending and adds its particles.
1221 //
1223
1224 std::ofstream File;
1225
1226 File.rdbuf()->pubsetbuf(io_buffer.dataPtr(), io_buffer.size());
1227
1228 File.open(filename.c_str(), std::ios::out|std::ios::app);
1229
1230 File.precision(15);
1231
1232 if (!File.good()) {
1233 amrex::FileOpenFailed(filename);
1234 }
1235
1236 for (int lev = 0; lev < std::ssize(m_particles); lev++) {
1237 auto& pmap = m_particles[lev];
1238 for (const auto& kv : pmap) {
1239 ParticleTile<ParticleType, NArrayReal, NArrayInt,
1241 pinned_ptile.define(NumRuntimeRealComps(), NumRuntimeIntComps(),
1242 nullptr, nullptr, The_Pinned_Arena());
1243 pinned_ptile.resize(kv.second.numParticles());
1244 amrex::copyParticles(pinned_ptile, kv.second);
1245 const auto& host_aos = pinned_ptile.GetArrayOfStructs();
1246 const auto& host_soa = pinned_ptile.GetStructOfArrays();
1247
1248 auto np = host_aos.numParticles();
1249 for (int index = 0; index < np; ++index) {
1250 const ParticleType* it = &host_aos[index];
1251 if (it->id().is_valid()) {
1252
1253 // write out the particle struct first...
1254 AMREX_D_TERM(File << it->pos(0) << ' ',
1255 << it->pos(1) << ' ',
1256 << it->pos(2) << ' ');
1257
1258 for (int i = 0; i < NStructReal; i++) {
1259 File << it->rdata(i) << ' ';
1260 }
1261
1262 File << it->id() << ' ';
1263 File << it->cpu() << ' ';
1264
1265 for (int i = 0; i < NStructInt; i++) {
1266 File << it->idata(i) << ' ';
1267 }
1268
1269 // then the particle attributes.
1270 for (int i = 0; i < NumRealComps(); i++) {
1271 File << host_soa.GetRealData(i)[index] << ' ';
1272 }
1273
1274 for (int i = 0; i < NumIntComps(); i++) {
1275 File << host_soa.GetIntData(i)[index] << ' ';
1276 }
1277
1278 File << '\n';
1279 }
1280 }
1281 }
1282 }
1283
1284 File.flush();
1285
1286 File.close();
1287
1288 if (!File.good()) {
1289 amrex::Abort("ParticleContainer::WriteAsciiFile(): problem writing file");
1290 }
1291
1292 }
1293
1295 }
1296
1297 if (m_verbose > 1)
1298 {
1299 auto stoptime = amrex::second() - strttime;
1300
1302
1303 amrex::Print() << "ParticleContainer::WriteAsciiFile() time: " << stoptime << '\n';
1304 }
1305}
1306
1307}
1308
1309#endif /*AMREX_PARTICLEIO_H*/
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
amrex::ParmParse pp
Input file parser instance for the given namespace.
Definition AMReX_HypreIJIface.cpp:15
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:172
A collection of Boxes stored in an Array.
Definition AMReX_BoxArray.H:564
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:43
static const IntDescriptor & NativeIntDescriptor()
Returns a constant reference to an IntDescriptor describing the native "int" under which AMReX was co...
Definition AMReX_FPC.cpp:76
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:88
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:172
A collection (stored as an array) of FArrayBox objects.
Definition AMReX_MultiFab.H:40
const std::string & FileName() const
Definition AMReX_NFiles.H:160
Dynamically allocated vector for trivially copyable data.
Definition AMReX_PODVector.H:308
iterator begin() noexcept
Definition AMReX_PODVector.H:674
Parse Parameters From Command Line and Input Files.
Definition AMReX_ParmParse.H:349
int query(std::string_view name, bool &ref, int ival=FIRST) const
Same as querykth() but searches for the last occurrence of name.
Definition AMReX_ParmParse.cpp:1947
A distributed container for Particles sorted onto the levels, grids, and tiles of a block-structured ...
Definition AMReX_ParticleContainer.H:149
T_ParticleType ParticleType
Definition AMReX_ParticleContainer.H:151
Definition AMReX_GpuAllocators.H:156
This class provides the user with a few print options.
Definition AMReX_Print.H:35
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
T * dataPtr() noexcept
get access to the underlying data pointer
Definition AMReX_Vector.H:49
Long size() const noexcept
Definition AMReX_Vector.H:53
static constexpr int IO_Buffer_Size
We try to do I/O with buffers of this size.
Definition AMReX_VisMFBuffer.H:16
static Long FileOffset(std::ostream &os)
The file offset of the passed ostream.
Definition AMReX_VisMF.cpp:580
static bool GetNoFlushAfterWrite()
Definition AMReX_VisMF.H:284
amrex_particle_real ParticleReal
Floating Point Type for Particles.
Definition AMReX_REAL.H:90
amrex_long Long
Definition AMReX_INT.H:30
void WritePlotFile(const std::string &dir, const std::string &name) const
This version of WritePlotFile writes all components and assigns component names.
Definition AMReX_ParticleIO.H:115
Arena * The_Pinned_Arena()
Definition AMReX_Arena.cpp:860
int MyProc() noexcept
Definition AMReX_ParallelDescriptor.H:128
void Barrier(const std::string &)
Definition AMReX_ParallelDescriptor.cpp:1215
void ReduceIntSum(int &)
Definition AMReX_ParallelDescriptor.cpp:1265
void ReadAndBcastFile(const std::string &filename, Vector< char > &charBuf, bool bExitOnError, const MPI_Comm &comm)
Definition AMReX_ParallelDescriptor.cpp:1495
int NProcs() noexcept
Definition AMReX_ParallelDescriptor.H:255
void ReduceLongSum(Long &)
Definition AMReX_ParallelDescriptor.cpp:1236
int IOProcessorNumber() noexcept
The MPI rank number of the I/O Processor (probably rank 0). This rank is usually used to write to std...
Definition AMReX_ParallelDescriptor.H:279
void ReduceLongMax(Long &)
Definition AMReX_ParallelDescriptor.cpp:1237
bool IOProcessor() noexcept
Is this CPU the I/O Processor? To get the rank number, call IOProcessorNumber()
Definition AMReX_ParallelDescriptor.H:289
bool UseAsyncOut()
Definition AMReX_AsyncOut.cpp:70
bool Remove(std::string const &filename)
Remove a file, symbolic link, or empty directory.
Definition AMReX_FileSystem.cpp:41
void copy(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
A host-to-device copy routine. Note this is just a wrapper around memcpy, so it assumes contiguous st...
Definition AMReX_GpuContainers.H:128
void copyAsync(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
A host-to-device copy routine. Note this is just a wrapper around memcpy, so it assumes contiguous st...
Definition AMReX_GpuContainers.H:228
static constexpr DeviceToHost deviceToHost
Definition AMReX_GpuContainers.H:106
static constexpr HostToDevice hostToDevice
Definition AMReX_GpuContainers.H:105
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:310
std::string const & name()
Definition AMReX_Machine.cpp:46
void ReduceRealMax(Vector< std::reference_wrapper< Real > > const &)
Definition AMReX_ParallelDescriptor.cpp:1228
Definition AMReX_Amr.cpp:50
void writeIntData(const From *data, std::size_t size, std::ostream &os, const amrex::IntDescriptor &id)
Definition AMReX_IntConv.H:23
__host__ __device__ void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:139
void WriteBinaryParticleDataSync(PC const &pc, const std::string &dir, const std::string &name, const Vector< int > &write_real_comp, const Vector< int > &write_int_comp, const Vector< std::string > &real_comp_names, const Vector< std::string > &int_comp_names, F const &f, bool is_checkpoint)
Definition AMReX_WriteBinaryParticleData.H:485
void FileOpenFailed(const std::string &file)
Output a message and abort when couldn't open the file.
Definition AMReX_Utility.cpp:137
void copyParticles(DstTile &dst, const SrcTile &src) noexcept
Copy particles from src to dst. This version copies all the particles, writing them to the beginning ...
Definition AMReX_ParticleTransformation.H:222
void readFloatData(float *data, std::size_t size, std::istream &is, const RealDescriptor &rd)
Definition AMReX_VectorIO.cpp:136
void writeFloatData(const float *data, std::size_t size, std::ostream &os, const RealDescriptor &rd=FPC::Native32RealDescriptor())
Definition AMReX_VectorIO.cpp:130
bool FileExists(const std::string &filename)
Check if a file already exists. Return true if the filename is an existing file, directory,...
Definition AMReX_Utility.cpp:145
__host__ __device__ Dim3 begin(BoxND< dim > const &box) noexcept
Definition AMReX_Box.H:2006
std::string Concatenate(const std::string &root, int num, int mindigits)
Returns rootNNNN where NNNN == num.
Definition AMReX_String.cpp:35
double second() noexcept
Definition AMReX_Utility.cpp:940
void writeDoubleData(const double *data, std::size_t size, std::ostream &os, const RealDescriptor &rd=FPC::Native64RealDescriptor())
Definition AMReX_VectorIO.cpp:142
void Error(const std::string &msg)
Print out message to cerr and exit via amrex::Abort().
Definition AMReX.cpp:235
void readDoubleData(double *data, std::size_t size, std::istream &is, const RealDescriptor &rd)
Definition AMReX_VectorIO.cpp:148
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:241
void WriteBinaryParticleDataAsync(PC const &pc, const std::string &dir, const std::string &name, const Vector< int > &write_real_comp, const Vector< int > &write_int_comp, const Vector< std::string > &real_comp_names, const Vector< std::string > &int_comp_names, bool is_checkpoint)
Definition AMReX_WriteBinaryParticleData.H:784
__host__ __device__ Dim3 end(BoxND< dim > const &box) noexcept
Definition AMReX_Box.H:2015
void readIntData(To *data, std::size_t size, std::istream &is, const amrex::IntDescriptor &id)
Definition AMReX_IntConv.H:38
Definition AMReX_ParticleIO.H:40
__host__ __device__ int operator()(const P &p) const
Definition AMReX_ParticleIO.H:43
FabArray memory allocation information.
Definition AMReX_FabArray.H:67
MFInfo & SetAlloc(bool a) noexcept
Definition AMReX_FabArray.H:74
uint64_t m_idcpu
Definition AMReX_Particle.H:359
__host__ __device__ bool is_valid() const noexcept
Definition AMReX_Particle.H:252
A struct used for storing a particle's position in the AMR hierarchy.
Definition AMReX_ParticleContainer.H:93
int m_tile
Definition AMReX_ParticleContainer.H:96
Definition AMReX_ParticleTile.H:764
The struct used to store particles.
Definition AMReX_Particle.H:405
__host__ __device__ RealVect pos() const &
Definition AMReX_Particle.H:456
__host__ __device__ int & idata(int index) &
Definition AMReX_Particle.H:545
__host__ __device__ ParticleCPUWrapper cpu() &
Definition AMReX_Particle.H:424
__host__ __device__ ParticleIDWrapper id() &
Definition AMReX_Particle.H:427
__host__ __device__ RealType & rdata(int index) &
Definition AMReX_Particle.H:474