4#include "MeshMetadata.h"
6#include <svtkPolyData.h>
7#include <svtkDataSetAttributes.h>
8#include <svtkCellData.h>
9#include <svtkPointData.h>
10#include <svtkMultiBlockDataSet.h>
21template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
22ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>*
23ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::New()
25 auto result =
new ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>;
26 result->InitializeObjectBase();
32template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
33int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::SetDataSource(
35 const std::map<std::string, std::vector<int>> & rStructs,
36 const std::map<std::string, int> & iStructs,
37 const std::map<std::string, std::vector<int>> & rArrays,
38 const std::map<std::string, int> & iArrays)
42 this->m_particles = particles;
45 int ret = this->SetArrayNames(rStructs, iStructs, rArrays, iArrays);
48 SENSEI_ERROR(
"problem with array names in SetDataSource");
55template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
56int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::SetArrayNames(
57 const std::map<std::string, std::vector<int>> & rStructs,
58 const std::map<std::string, int> & iStructs,
59 const std::map<std::string, std::vector<int>> & rArrays,
60 const std::map<std::string, int> & iArrays)
62 if(rStructs.size() <= ParticleType::NReal)
65 for(
auto s : rStructs)
69 if(i >= ParticleType::NReal)
71 SENSEI_ERROR(
"rStruct index exceeds internal storage size");
76 m_realStructs = rStructs;
80 SENSEI_ERROR(
"rStructs array size exceeds internal storage size");
84 if(iStructs.size() <= ParticleType::NInt)
87 for(
auto s : iStructs)
89 if(s.second >= ParticleType::NInt)
91 SENSEI_ERROR(
"iStructs index exceeds internal storage size");
95 m_intStructs = iStructs;
99 SENSEI_ERROR(
"iStructs array size exceeds internal storage size");
104 if(rArrays.size() <= NArrayReal)
107 for(
auto s : rArrays)
113 SENSEI_ERROR(
"rArrays index exceeds internal storage size");
118 m_realArrays = rArrays;
122 SENSEI_ERROR(
"rArrays array size exceeds internal storage size");
125 if(iArrays.size() <= NArrayInt)
128 for(
auto s : iArrays)
130 if(s.second >= NArrayInt)
132 SENSEI_ERROR(
"iArray index exceeds internal storage size");
136 m_intArrays = iArrays;
140 SENSEI_ERROR(
"iArrays array size exceeds internal storage size");
146template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
147int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::GetNumberOfMeshes(
unsigned int &numMeshes)
154#if SENSEI_VERSION_MAJOR < 3
155template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
156int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::GetMeshName(
157 unsigned int id, std::string &meshName)
159 meshName = m_particlesName;
165#if SENSEI_VERSION_MAJOR < 3
166template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
167int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::GetMeshHasGhostNodes(
168 const std::string &meshName,
177#if SENSEI_VERSION_MAJOR < 3
178template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
179int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::GetMeshHasGhostCells(
180 const std::string &meshName,
189#if SENSEI_VERSION_MAJOR < 3
190template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
191int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::GetNumberOfArrays(
192 const std::string &meshName,
194 unsigned int &numberOfArrays)
197 if(association == svtkDataObject::POINT)
199 numberOfArrays = m_realStructs.size()
200 + m_intStructs.size()
201 + m_realArrays.size()
202 + m_intArrays.size();
208#if SENSEI_VERSION_MAJOR < 3
209template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
210int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::GetArrayName(
211 const std::string &meshName,
214 std::string &arrayName)
216 if(association == svtkDataObject::POINT)
218 if(index < m_realStructs.size())
220 auto a = m_realStructs.begin() + index;
221 arrayName = *(a).first;
224 if(index < m_intStructs.size())
226 int ind = index - m_realStructs.size();
227 auto a = m_intStructs.begin() + ind;
228 arrayName = *(a).first;
231 if(index < m_realArrays.size())
233 int ind = index - m_realStructs.size() - m_intStructs.size();
234 auto a = m_realArrays.begin() + ind;
235 arrayName = *(a).first;
238 if(index < m_intArrays.size())
240 int ind = index - m_realStructs.size() - m_intStructs.size() - m_realArrays.size();
241 auto a = m_intArrays.begin() + ind;
242 arrayName = *(a).first;
252template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
253int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::GetMesh(
254 const std::string &meshName,
256 svtkDataObject *&mesh)
261 MPI_Comm_size(this->GetCommunicator(), &nprocs);
262 MPI_Comm_rank(this->GetCommunicator(), &rank);
264 if (meshName != m_particlesName)
266 SENSEI_ERROR(
"No mesh named \"" << meshName <<
"\"")
269 svtkMultiBlockDataSet* mb = svtkMultiBlockDataSet::New();
277 mb->SetNumberOfBlocks(nprocs);
278 svtkPolyData *pd = BuildParticles();
279 mb->SetBlock(rank, pd);
287template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
288int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddGhostNodesArray(
290 const std::string &meshName)
292 if (meshName != m_particlesName)
294 SENSEI_ERROR(
"no mesh named \"" << meshName <<
"\"")
301template <typename ParticleType,
int NArrayReal,
int NArrayInt>
302int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddGhostCellsArray(
304 const std::
string &meshName)
306 if (meshName != m_particlesName)
308 SENSEI_ERROR(
"no mesh named \"" << meshName <<
"\"")
315template <typename ParticleType,
int NArrayReal,
int NArrayInt>
316int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddArray(
317 svtkDataObject* mesh,
318 const std::
string &meshName,
320 const std::
string &arrayName)
322 if (meshName != m_particlesName)
324 SENSEI_ERROR(
"no mesh named \"" << meshName <<
"\"");
328 if (association != svtkDataObject::POINT)
330 SENSEI_ERROR(
"Invalid association " << association);
334 if(m_realStructs.find(arrayName) != m_realStructs.end())
336 return this->AddParticlesAOSRealArray(arrayName, mesh);
339 if(m_intStructs.find(arrayName) != m_intStructs.end())
341 return this->AddParticlesAOSIntArray(arrayName, mesh);
344 if(m_realArrays.find(arrayName) != m_realArrays.end())
346 return this->AddParticlesSOARealArray(arrayName, mesh);
349 if(m_intArrays.find(arrayName) != m_intArrays.end())
351 return this->AddParticlesSOAIntArray(arrayName, mesh);
354 SENSEI_ERROR(
"Invalid array name " << arrayName);
359template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
360int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::ReleaseData()
362 this->m_particles =
nullptr;
367#if SENSEI_VERSION_MAJOR >= 3
368template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
369int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::GetMeshMetadata(
371 sensei::MeshMetadataPtr &metadata)
373 sensei::TimeEvent<64> event(
"AmrMeshDataAdaptor::GetMeshMetadata");
377 MPI_Comm_size(this->GetCommunicator(), &nprocs);
378 MPI_Comm_rank(this->GetCommunicator(), &rank);
379 if (
id != 0 &&
id != 1)
381 SENSEI_ERROR(
"invalid mesh id " <<
id)
387 metadata->GlobalView =
false;
393 metadata->MeshName = m_particlesName;
396 metadata->MeshType = SVTK_MULTIBLOCK_DATA_SET;
399 metadata->BlockType = SVTK_POLY_DATA;
402 metadata->NumBlocks = nprocs;
405 metadata->NumBlocksLocal = {1};
414#ifdef AMREX_SINGLE_PRECISION_PARTICLES
415 metadata->CoordinateType = SVTK_FLOAT;
417 metadata->CoordinateType = SVTK_DOUBLE;
430 metadata->NumArrays = m_realStructs.size()
431 + m_intStructs.size()
432 + m_realArrays.size()
433 + m_intArrays.size();
436 metadata->NumGhostCells = 0;
439 metadata->NumGhostNodes = 0;
445 metadata->StaticMesh = 0;
448 metadata->ArrayName = {};
449 for(
auto s : m_realStructs)
451 metadata->ArrayName.push_back(s.first);
453 for(
auto s : m_intStructs)
455 metadata->ArrayName.push_back(s.first);
457 for(
auto s : m_realArrays)
459 metadata->ArrayName.push_back(s.first);
461 for(
auto s : m_intArrays)
463 metadata->ArrayName.push_back(s.first);
467 metadata->ArrayCentering = {};
468 for(
auto s : m_realStructs)
470 metadata->ArrayCentering.push_back(svtkDataObject::POINT);
472 for(
auto s : m_intStructs)
474 metadata->ArrayCentering.push_back(svtkDataObject::POINT);
476 for(
auto s : m_realArrays)
478 metadata->ArrayCentering.push_back(svtkDataObject::POINT);
480 for(
auto s : m_intArrays)
482 metadata->ArrayCentering.push_back(svtkDataObject::POINT);
486 metadata->ArrayComponents = {};
487 for(
auto s : m_realStructs)
489 metadata->ArrayComponents.push_back(s.second.size());
491 for(
auto s : m_intStructs)
493 metadata->ArrayComponents.push_back(1);
495 for(
auto s : m_realArrays)
497 metadata->ArrayComponents.push_back(s.second.size());
499 for(
auto s : m_intArrays)
501 metadata->ArrayComponents.push_back(1);
505 metadata->ArrayType = {};
506 for(
auto s : m_realStructs)
508#ifdef AMREX_SINGLE_PRECISION_PARTICLES
509 metadata->ArrayType.push_back(SVTK_FLOAT);
511 metadata->ArrayType.push_back(SVTK_DOUBLE);
514 for(
auto s : m_intStructs)
516 metadata->ArrayType.push_back(SVTK_INT);
518 for(
auto s : m_realArrays)
520#ifdef AMREX_SINGLE_PRECISION_PARTICLES
521 metadata->ArrayType.push_back(SVTK_FLOAT);
523 metadata->ArrayType.push_back(SVTK_DOUBLE);
526 for(
auto s : m_intArrays)
528 metadata->ArrayType.push_back(SVTK_INT);
535 metadata->BlockOwner = {rank};
538 metadata->BlockIds = metadata->BlockOwner;
541 auto nptsOnProc = this->m_particles->TotalNumberOfParticles(
true,
true);
542 metadata->BlockNumPoints = {nptsOnProc};
545 metadata->BlockNumCells = {nptsOnProc};
548 metadata->BlockCellArraySize = {nptsOnProc};
556 if (metadata->Flags.BlockBoundsSet())
558 std::array<double,6> bounds({
559 std::numeric_limits<double>::max(),
560 std::numeric_limits<double>::lowest(),
561#if (AMREX_SPACEDIM == 1)
563#elif (AMREX_SPACEDIM == 2)
564 std::numeric_limits<double>::max(),
565 std::numeric_limits<double>::lowest(),
567#elif (AMREX_SPACEDIM == 3)
568 std::numeric_limits<double>::max(),
569 std::numeric_limits<double>::lowest(),
570 std::numeric_limits<double>::max(),
571 std::numeric_limits<double>::lowest()
576 const auto& particles = this->m_particles->
GetParticles();
577 for (
int lev = 0; lev < particles.size(); lev++)
580 auto& pmap = particles[lev];
581 for (
const auto& kv : pmap)
584 auto& particle_tile = kv.second;
585 auto ptd = particle_tile.getConstParticleTileData();
588 long long numReal = particle_tile.numRealParticles();
589 for (
long long i = 0; i < numReal; ++i)
591 const auto &part = ptd[i];
592 if (part.id().is_valid())
594#if (AMREX_SPACEDIM == 1)
595 bounds[0] = bounds[0] > part.pos(0) ? part.pos(0) : bounds[0];
596 bounds[1] = bounds[1] < part.pos(0) ? part.pos(0) : bounds[1];
597#elif (AMREX_SPACEDIM == 2)
598 bounds[0] = bounds[0] > part.pos(0) ? part.pos(0) : bounds[0];
599 bounds[1] = bounds[1] < part.pos(0) ? part.pos(0) : bounds[1];
600 bounds[2] = bounds[2] > part.pos(1) ? part.pos(1) : bounds[2];
601 bounds[3] = bounds[3] < part.pos(1) ? part.pos(1) : bounds[3];
602#elif (AMREX_SPACEDIM == 3)
603 bounds[0] = bounds[0] > part.pos(0) ? part.pos(0) : bounds[0];
604 bounds[1] = bounds[1] < part.pos(0) ? part.pos(0) : bounds[1];
605 bounds[2] = bounds[2] > part.pos(1) ? part.pos(1) : bounds[2];
606 bounds[3] = bounds[3] < part.pos(1) ? part.pos(1) : bounds[3];
607 bounds[4] = bounds[4] > part.pos(2) ? part.pos(2) : bounds[4];
608 bounds[5] = bounds[5] < part.pos(2) ? part.pos(2) : bounds[5];
615 metadata->BlockBounds = {bounds};
621 if (metadata->Flags.BlockArrayRangeSet())
623 SENSEI_ERROR(
"BlockArrayRange requested but not yet implemented.")
638#if defined(SENSEI_DEBUG)
639 metadata->Validate(this->GetCommunicator(), sensei::MeshMetadataFlags());
640 metadata->ToStream(std::cerr);
648template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
649svtkPolyData* ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::BuildParticles()
652 svtkPolyData* pd = svtkPolyData::New();
654 const auto& particles = this->m_particles->GetParticles();
655 long long numParticles = this->m_particles->TotalNumberOfParticles(
true,
true);
658#ifdef AMREX_SINGLE_PRECISION_PARTICLES
659 svtkNew<svtkFloatArray> coords;
661 svtkNew<svtkDoubleArray> coords;
663 coords->SetName(
"coords");
664 coords->SetNumberOfComponents(3);
665 coords->SetNumberOfTuples(numParticles);
666#ifdef AMREX_SINGLE_PRECISION_PARTICLES
667 float *pCoords = coords->GetPointer(0);
669 double *pCoords = coords->GetPointer(0);
677 svtkNew<svtkCellArray> vertex;
678 vertex->AllocateExact(numParticles, 1);
683 for (
int lev = 0; lev < particles.size(); lev++)
685 using MyParIter = ParIter_impl<ParticleType, NArrayReal, NArrayInt>;
686 for (MyParIter pti(*this->m_particles, lev); pti.isValid(); ++pti)
688 auto ptd = pti.GetParticleTile().getParticleTileData();
689 auto numReal = pti.numParticles();
691 for (
long long i = 0; i < numReal; ++i)
693 const auto& part = ptd[i];
694 if (part.id().is_valid())
697 vertex->InsertNextCell(1);
698 vertex->InsertCellPoint(ptId);
700#if (AMREX_SPACEDIM == 1)
701 pCoords[0] = part.pos(0);
704#elif (AMREX_SPACEDIM == 2)
705 pCoords[0] = part.pos(0);
706 pCoords[1] = part.pos(1);
708#elif (AMREX_SPACEDIM == 3)
709 pCoords[0] = part.pos(0);
710 pCoords[1] = part.pos(1);
711 pCoords[2] = part.pos(2);
721 svtkNew<svtkPoints> points;
722 points->SetData(coords);
725 pd->SetPoints(points);
726 pd->SetVerts(vertex);
732template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
733int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddParticlesIDArray(
734 svtkDataObject* mesh)
736 auto svtk_particles =
dynamic_cast<svtkPolyData*
>(mesh);
737 const auto& particles = this->m_particles->GetParticles();
738 auto nptsOnProc = this->m_particles->TotalNumberOfParticles(
true,
true);
741 svtkNew<svtkIntArray> idArray;
742 idArray->SetName(
"id");
743 idArray->SetNumberOfComponents(1);
744 idArray->SetNumberOfValues(nptsOnProc);
747 int *partIds = idArray->GetPointer(0);
750 using MyParIter = ParIter_impl<ParticleType, NArrayReal, NArrayInt>;
752 for (
int level = 0; level < particles.size(); ++level)
754 for (MyParIter pti(*this->m_particles, level); pti.isValid(); ++pti)
756 auto ptd = pti.GetParticleTile().getParticleTileData();
757 auto numReal = pti.numParticles();
758 for (
long long i = 0; i < numReal; ++i)
760 if (ptd.id(i).is_valid())
762 partIds[i] = ptd.id(i);
770 svtk_particles->GetPointData()->AddArray(idArray);
776template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
777int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddParticlesCPUArray(
778 svtkDataObject* mesh)
780 auto svtk_particles =
dynamic_cast<svtkPolyData*
>(mesh);
781 const auto& particles = this->m_particles->GetParticles();
782 auto nptsOnProc = this->m_particles->TotalNumberOfParticles(
true,
true);
785 svtkNew<svtkIntArray> cpuArray;
786 cpuArray->SetName(
"cpu");
787 cpuArray->SetNumberOfComponents(1);
788 cpuArray->SetNumberOfValues(nptsOnProc);
791 int* partCpu = cpuArray->GetPointer(0);
794 using MyParIter = ParIter_impl<ParticleType, NArrayReal, NArrayInt>;
795 for (
int level = 0; level < particles.size(); ++level)
797 for (MyParIter pti(*this->m_particles, level); pti.isValid(); ++pti)
799 auto ptd = pti.GetParticleTile().getParticleTileData();
800 auto numReal = pti.numParticles();
801 for (
long long i = 0; i < numReal; ++i)
803 if (ptd.id(i).is_valid())
805 partCpu[i] = ptd.cpu(i);
813 svtk_particles->GetPointData()->AddArray(cpuArray);
819template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
820int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddParticlesSOARealArray(
821 const std::string &arrayName,
822 svtkDataObject* mesh)
824 const long nParticles = this->m_particles->TotalNumberOfParticles(
true,
true);
827 RealDataMapType::iterator ait = m_realArrays.find(arrayName);
828 if (ait == m_realArrays.end())
830 SENSEI_ERROR(
"No real SOA named \"" << arrayName <<
"\"");
835 const std::vector<int> &indices = ait->second;
836 int nComps = indices.size();
839 for(
auto i : indices)
843 SENSEI_ERROR(
"Index out of bounds for real SOA named \"" << arrayName <<
"\"");
849#ifdef AMREX_SINGLE_PRECISION_PARTICLES
850 svtkNew<svtkFloatArray> data;
852 svtkNew<svtkDoubleArray> data;
854 data->SetName(arrayName.c_str());
855 data->SetNumberOfComponents(nComps);
856 data->SetNumberOfTuples(nParticles);
858#ifdef AMREX_SINGLE_PRECISION_PARTICLES
859 float* pData = data->GetPointer(0);
861 double* pData = data->GetPointer(0);
864 using MyParIter = ParIter_impl<ParticleType, NArrayReal, NArrayInt>;
865 for (
int level = 0; level < this->m_particles->numLevels(); ++level)
867 for (MyParIter pti(*this->m_particles, level); pti.isValid(); ++pti)
869 auto& particle_attributes = pti.GetStructOfArrays();
870 auto ptd = pti.GetParticleTile().getParticleTileData();
872 auto numReal = pti.numParticles();
874 for (
int j = 0; j < nComps; ++j)
876 int compInd = indices[j];
878 const auto &realData = particle_attributes.GetRealData(compInd);
880 for (
long long i = 0; i < numReal; ++i)
882 const auto &part = ptd[i];
883 if (part.id().is_valid())
885 pData[i*nComps + j] = realData[i];
889 pData += numReal * nComps;
895 MPI_Comm_rank(this->GetCommunicator(), &rank);
897 auto blocks =
dynamic_cast<svtkMultiBlockDataSet*
>(mesh);
899 auto block =
dynamic_cast<svtkPolyData*
>(blocks->GetBlock(rank));
900 block->GetPointData()->AddArray(data);
906template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
907int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddParticlesSOAIntArray(
908 const std::string &arrayName,
909 svtkDataObject* mesh)
912 auto nptsOnProc = this->m_particles->TotalNumberOfParticles(
true,
true);
915 IntDataMapType::iterator ait = m_intArrays.find(arrayName);
916 if (ait == m_intArrays.end())
918 SENSEI_ERROR(
"No int SOA named \"" << arrayName <<
"\"");
923 int index = ait->second;
926 if(index >= NArrayInt)
928 SENSEI_ERROR(
"Index out of bounds for int SOA named \"" << arrayName <<
"\"");
932 svtkNew<svtkIntArray> data;
933 data->SetName(arrayName.c_str());
934 data->SetNumberOfComponents(1);
935 data->SetNumberOfValues(nptsOnProc);
936 int* pData = data->GetPointer(0);
939 using MyParIter = ParIter_impl<ParticleType, NArrayReal, NArrayInt>;
940 for (
int level = 0; level< this->m_particles->numLevels(); level++)
942 for (MyParIter pti(*this->m_particles, level); pti.isValid(); ++pti)
944 auto& particle_attributes = pti.GetStructOfArrays();
945 auto ptd = pti.GetParticleTile().getParticleTileData();
947 auto numReal = pti.numParticles();
950 const auto &intData = particle_attributes.GetIntData(index);
952 for (
long long i = 0; i < numReal; ++i)
954 const auto &part = ptd[i];
955 if (part.id().is_valid())
957 pData[i] = intData[i];
966 MPI_Comm_rank(this->GetCommunicator(), &rank);
968 auto blocks =
dynamic_cast<svtkMultiBlockDataSet*
>(mesh);
970 auto block =
dynamic_cast<svtkPolyData*
>(blocks->GetBlock(rank));
971 block->GetPointData()->AddArray(data);
977template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
978int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddParticlesAOSRealArray(
979 const std::string &arrayName,
980 svtkDataObject* mesh)
983 const auto& particles = this->m_particles->GetParticles();
984 auto nptsOnProc = this->m_particles->TotalNumberOfParticles(
true,
true);
987 RealDataMapType::iterator ait = m_realStructs.find(arrayName);
988 if (ait == m_realStructs.end())
990 SENSEI_ERROR(
"No real AOS named \"" << arrayName <<
"\"");
995 std::vector<int> indices = ait->second;
996 int nComps = indices.size();
999 for (
auto i : indices)
1001 if (i >= ParticleType::NReal)
1003 SENSEI_ERROR(
"Index out of bounds for real AOS named \"" << arrayName <<
"\"");
1009#ifdef AMREX_SINGLE_PRECISION_PARTICLES
1010 svtkNew<svtkFloatArray> data;
1012 svtkNew<svtkDoubleArray> data;
1015 data->SetName(arrayName.c_str());
1016 data->SetNumberOfComponents(nComps);
1017 data->SetNumberOfTuples(nptsOnProc);
1019#ifdef AMREX_SINGLE_PRECISION_PARTICLES
1020 float *pData = data->GetPointer(0);
1022 double *pData = data->GetPointer(0);
1025 if constexpr(!ParticleType::is_soa_particle) {
1028 using MyParIter = ParIter_impl<ParticleType, NArrayReal, NArrayInt>;
1029 for (
int level = 0; level<particles.size();level++)
1031 for (MyParIter pti(*this->m_particles, level); pti.isValid(); ++pti)
1033 auto& aos = pti.GetArrayOfStructs();
1035 auto numReal = pti.numParticles();
1037 for (
int j = 0; j < nComps; ++j)
1039 for (
long long i = 0; i < numReal; ++i)
1041 const auto &part = aos[i];
1042 if (part.id().is_valid())
1044 pData[i*nComps + j] = part.rdata(indices[j]);
1048 pData += numReal * nComps;
1054 MPI_Comm_rank(this->GetCommunicator(), &rank);
1056 auto blocks =
dynamic_cast<svtkMultiBlockDataSet*
>(mesh);
1058 auto block =
dynamic_cast<svtkPolyData*
>(blocks->GetBlock(rank));
1059 block->GetPointData()->AddArray(data);
1067template <
typename ParticleType,
int NArrayReal,
int NArrayInt>
1068int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddParticlesAOSIntArray(
1069 const std::string &arrayName,
1070 svtkDataObject* mesh)
1073 const auto& particles = this->m_particles->GetParticles();
1075 auto nptsOnProc = this->m_particles->TotalNumberOfParticles(
true,
true);
1078 IntDataMapType::iterator ait = m_intStructs.find(arrayName);
1079 if (ait == m_intStructs.end())
1081 SENSEI_ERROR(
"No int AOS named \"" << arrayName <<
"\"");
1086 int index = ait->second;
1089 if(index >= ParticleType::NInt)
1091 SENSEI_ERROR(
"Index out of bounds for int AOS named \"" << arrayName <<
"\"");
1095 if constexpr(!ParticleType::is_soa_particle) {
1098 svtkNew<svtkIntArray> data;
1099 data->SetName(arrayName.c_str());
1100 data->SetNumberOfComponents(1);
1101 data->SetNumberOfValues(nptsOnProc);
1102 int* pData = data->GetPointer(0);
1104 using MyParIter = ParIter_impl<ParticleType, NArrayReal, NArrayInt>;
1105 for (
int level = 0; level<particles.size(); ++level)
1107 for (MyParIter pti(*this->m_particles, level); pti.isValid(); ++pti)
1109 const auto& aos = pti.GetArrayOfStructs();
1111 long long numReal = pti.numParticles();
1112 for (
long long i = 0; i < numReal; ++i)
1114 const auto &part = aos[i];
1115 if (part.id().is_valid())
1117 pData[i] = part.idata(index);
1126 MPI_Comm_rank(this->GetCommunicator(), &rank);
1128 auto blocks =
dynamic_cast<svtkMultiBlockDataSet*
>(mesh);
1130 auto block =
dynamic_cast<svtkPolyData*
>(blocks->GetBlock(rank));
1131 block->GetPointData()->AddArray(data);
double amrex_particle_real
Definition AMReX_REAL.H:64
if(!(yy_init))
Definition amrex_iparser.lex.nolint.H:935
A distributed container for Particles sorted onto the levels, grids, and tiles of a block-structured ...
Definition AMReX_ParticleContainer.H:146
const Vector< ParticleLevel > & GetParticles() const
Return the underlying Vector (over AMR levels) of ParticleLevels. Const version.
Definition AMReX_ParticleContainer.H:1000
Definition AMReX_Amr.cpp:49
double second() noexcept
Definition AMReX_Utility.cpp:928