1717#include < array>
1818#include < memory>
1919#include < limits>
20+ #include < numeric>
2021
2122using namespace openPMD ;
2223
@@ -111,6 +112,88 @@ void constant_scalar(std::string file_ending)
111112 }
112113}
113114
115+ inline
116+ void particle_patches ( std::string file_ending )
117+ {
118+ constexpr auto SCALAR = openPMD::RecordComponent::SCALAR;
119+
120+ uint64_t const extent = 123u ;
121+ uint64_t const num_patches = 2u ;
122+ {
123+ // constant scalar
124+ Series s = Series (" ../samples/particle_patches." + file_ending, AccessType::CREATE);
125+
126+ auto e = s.iterations [42 ].particles [" electrons" ];
127+
128+ for ( auto r : {" x" , " y" } )
129+ {
130+ auto x = e[" position" ][r];
131+ x.resetDataset (Dataset (determineDatatype<float >(), {extent}));
132+ std::vector<float > xd ( extent );
133+ std::iota (xd.begin (), xd.end (), 0 );
134+ x.storeChunk ({0 }, {extent}, shareRaw (xd.data ()));
135+ auto o = e[" positionOffset" ][r];
136+ o.resetDataset (Dataset (determineDatatype<uint64_t >(), {extent}));
137+ std::vector<uint64_t > od ( extent );
138+ std::iota (od.begin (), od.end (), 0 );
139+ o.storeChunk ({0 }, {extent}, shareRaw (od.data ()));
140+ }
141+
142+ auto const dset_n = Dataset (determineDatatype<uint64_t >(), {num_patches, });
143+ e.particlePatches [" numParticles" ][SCALAR].resetDataset (dset_n);
144+ e.particlePatches [" numParticlesOffset" ][SCALAR].resetDataset (dset_n);
145+
146+ auto const dset_f = Dataset (determineDatatype<float >(), {num_patches, });
147+ e.particlePatches [" offset" ][" x" ].resetDataset (dset_f);
148+ e.particlePatches [" offset" ][" y" ].resetDataset (dset_f);
149+ e.particlePatches [" extent" ][" x" ].resetDataset (dset_f);
150+ e.particlePatches [" extent" ][" y" ].resetDataset (dset_f);
151+
152+ // patch 0 (decomposed in x)
153+ e.particlePatches [" numParticles" ][SCALAR].store (0 , uint64_t (10u ));
154+ e.particlePatches [" numParticlesOffset" ][SCALAR].store (0 , uint64_t (0u ));
155+ e.particlePatches [" offset" ][" x" ].store (0 , float (0 .));
156+ e.particlePatches [" offset" ][" y" ].store (0 , float (0 .));
157+ e.particlePatches [" extent" ][" x" ].store (0 , float (10 .));
158+ e.particlePatches [" extent" ][" y" ].store (0 , float (123 .));
159+
160+ // patch 1 (decomposed in x)
161+ e.particlePatches [" numParticles" ][SCALAR].store (1 , uint64_t (113u ));
162+ e.particlePatches [" numParticlesOffset" ][SCALAR].store (1 , uint64_t (10u ));
163+ e.particlePatches [" offset" ][" x" ].store (1 , float (10 .));
164+ e.particlePatches [" offset" ][" y" ].store (1 , float (0 .));
165+ e.particlePatches [" extent" ][" x" ].store (1 , float (113 ));
166+ e.particlePatches [" extent" ][" y" ].store (1 , float (123 .));
167+ }
168+ {
169+ Series s = Series (" ../samples/particle_patches." + file_ending, AccessType::READ_ONLY);
170+
171+ auto e = s.iterations [42 ].particles [" electrons" ];
172+
173+ auto numParticles = e.particlePatches [" numParticles" ][SCALAR].template load < uint64_t >();
174+ auto numParticlesOffset = e.particlePatches [" numParticlesOffset" ][SCALAR].template load < uint64_t >();
175+ auto extent_x = e.particlePatches [" extent" ][" x" ].template load < float >();
176+ auto extent_y = e.particlePatches [" extent" ][" y" ].template load < float >();
177+ auto offset_x = e.particlePatches [" offset" ][" x" ].template load < float >();
178+ auto offset_y = e.particlePatches [" offset" ][" y" ].template load < float >();
179+
180+ s.flush ();
181+
182+ REQUIRE (numParticles.get ()[0 ] == 10 );
183+ REQUIRE (numParticles.get ()[1 ] == 113 );
184+ REQUIRE (numParticlesOffset.get ()[0 ] == 0 );
185+ REQUIRE (numParticlesOffset.get ()[1 ] == 10 );
186+ REQUIRE (extent_x.get ()[0 ] == 10 .);
187+ REQUIRE (extent_x.get ()[1 ] == 113 .);
188+ REQUIRE (extent_y.get ()[0 ] == 123 .);
189+ REQUIRE (extent_y.get ()[1 ] == 123 .);
190+ REQUIRE (offset_x.get ()[0 ] == 0 .);
191+ REQUIRE (offset_x.get ()[1 ] == 10 .);
192+ REQUIRE (offset_y.get ()[0 ] == 0 .);
193+ REQUIRE (offset_y.get ()[1 ] == 0 .);
194+ }
195+ }
196+
114197#if openPMD_HAVE_HDF5
115198TEST_CASE ( " git_hdf5_sample_structure_test" , " [serial][hdf5]" )
116199{
@@ -554,7 +637,8 @@ TEST_CASE( "hzdr_hdf5_sample_content_test", "[serial][hdf5]" )
554637 // since this file might not be publicly available, gracefully handle errors
555638 try
556639 {
557- /* development/huebl/lwfa-openPMD-062-smallLWFA-h5 */
640+ /* HZDR: /bigdata/hplsim/development/huebl/lwfa-openPMD-062-smallLWFA-h5
641+ * DOI:10.14278/rodare.57 */
558642 Series o = Series (" ../samples/hzdr-sample/h5/simData_%T.h5" , AccessType::READ_ONLY);
559643
560644 REQUIRE (o.openPMD () == " 1.0.0" );
@@ -907,10 +991,13 @@ TEST_CASE( "hzdr_hdf5_sample_content_test", "[serial][hdf5]" )
907991#endif
908992 REQUIRE (isSame (e_extent_z.getDatatype (), determineDatatype< uint64_t >()));
909993
910- std::shared_ptr < uint64_t > data;
911- e_extent_z.load (0 , data);
994+ std::vector < uint64_t > data ( e_patches. size () ) ;
995+ e_extent_z.load (shareRaw ( data. data ()) );
912996 o.flush ();
913- REQUIRE (*data == static_cast < uint64_t >(80 ));
997+ REQUIRE (data.at (0 ) == static_cast < uint64_t >(80 ));
998+ REQUIRE (data.at (1 ) == static_cast < uint64_t >(80 ));
999+ REQUIRE (data.at (2 ) == static_cast < uint64_t >(80 ));
1000+ REQUIRE (data.at (3 ) == static_cast < uint64_t >(80 ));
9141001
9151002 PatchRecord& e_numParticles = e_patches[" numParticles" ];
9161003 REQUIRE (e_numParticles.size () == 1 );
@@ -922,9 +1009,12 @@ TEST_CASE( "hzdr_hdf5_sample_content_test", "[serial][hdf5]" )
9221009#endif
9231010 REQUIRE (isSame (e_numParticles_scalar.getDatatype (), determineDatatype< uint64_t >()));
9241011
925- e_numParticles_scalar.load (0 , data);
1012+ e_numParticles_scalar.load (shareRaw ( data. data ()) );
9261013 o.flush ();
927- REQUIRE (*data == static_cast < uint64_t >(512000 ));
1014+ REQUIRE (data.at (0 ) == static_cast < uint64_t >(512000 ));
1015+ REQUIRE (data.at (1 ) == static_cast < uint64_t >(819200 ));
1016+ REQUIRE (data.at (2 ) == static_cast < uint64_t >(819200 ));
1017+ REQUIRE (data.at (3 ) == static_cast < uint64_t >(0 ));
9281018
9291019 PatchRecord& e_numParticlesOffset = e_patches[" numParticlesOffset" ];
9301020 REQUIRE (e_numParticlesOffset.size () == 1 );
@@ -958,6 +1048,13 @@ TEST_CASE( "hzdr_hdf5_sample_content_test", "[serial][hdf5]" )
9581048#endif
9591049 REQUIRE (isSame (e_offset_y.getDatatype (), determineDatatype< uint64_t >()));
9601050
1051+ e_offset_y.load (shareRaw (data.data ()));
1052+ o.flush ();
1053+ REQUIRE (data.at (0 ) == static_cast < uint64_t >(0 ));
1054+ REQUIRE (data.at (1 ) == static_cast < uint64_t >(128 ));
1055+ REQUIRE (data.at (2 ) == static_cast < uint64_t >(256 ));
1056+ REQUIRE (data.at (3 ) == static_cast < uint64_t >(384 ));
1057+
9611058 PatchRecordComponent& e_offset_z = e_offset[" z" ];
9621059 REQUIRE (e_offset_z.unitSI () == 2.599999993753294e-07 );
9631060#if !defined(_MSC_VER)
@@ -1540,6 +1637,11 @@ TEST_CASE( "hdf5_constant_scalar", "[serial][hdf5]" )
15401637{
15411638 constant_scalar (" h5" );
15421639}
1640+
1641+ TEST_CASE ( " hdf5_particle_patches" , " [serial][hdf5]" )
1642+ {
1643+ particle_patches (" h5" );
1644+ }
15431645#else
15441646TEST_CASE ( " no_serial_hdf5" , " [serial][hdf5]" )
15451647{
@@ -1999,7 +2101,8 @@ TEST_CASE( "hzdr_adios1_sample_content_test", "[serial][adios1]" )
19992101 /* * @todo add bp example files to https://github.com/openPMD/openPMD-example-datasets */
20002102 try
20012103 {
2002- /* development/huebl/lwfa-bgfield-001 */
2104+ /* HZDR: /bigdata/hplsim/development/huebl/lwfa-bgfield-001
2105+ * DOI:10.14278/rodare.57 */
20032106 Series o = Series (" ../samples/hzdr-sample/bp/checkpoint_%T.bp" , AccessType::READ_ONLY);
20042107
20052108 REQUIRE (o.openPMD () == " 1.0.0" );
@@ -2156,6 +2259,10 @@ TEST_CASE( "adios1_constant_scalar", "[serial][adios1]" )
21562259{
21572260 constant_scalar (" bp" );
21582261}
2262+ TEST_CASE ( " adios1_particle_patches" , " [serial][adios1]" )
2263+ {
2264+ particle_patches (" bp" );
2265+ }
21592266#else
21602267TEST_CASE ( " no_serial_adios1" , " [serial][adios]" )
21612268{
0 commit comments