22#define PARTICLE_TYPES_HPP_
33
44#include " AMReX_AmrParticles.H"
5+ #include " AMReX_Enum.H"
56#include " AMReX_ParIter.H"
67#include " physics_info.hpp"
78
@@ -87,12 +88,17 @@ AMREX_ENUM(SNScheme, // NOLINT
8788
8889// -------------------- Radiation particles --------------------
8990
90- // Indices for radiation particles (Rad_particles), birth time + death time + radiation groups
91- enum RadParticleDataIdx {
92- RadParticleBirthTimeIdx = 0 , // Time when particle becomes active
93- RadParticleDeathTimeIdx, // Time when particle becomes inactive
94- RadParticleLumIdx // Base index for luminosity components
95- };
91+ // Indices for radiation particles (Rad_particles) using AMREX_ENUM for automatic string conversion
92+ AMREX_ENUM (RadParticleRealIdx, // NOLINT
93+ birth_time, // Time when particle becomes active
94+ death_time, // Time when particle becomes inactive
95+ luminosity // Base luminosity component (expanded to luminosity_0, luminosity_1, ... in I/O)
96+ );
97+
98+ // Backward compatibility aliases for existing code
99+ constexpr int RadParticleBirthTimeIdx = static_cast <int >(RadParticleRealIdx::birth_time);
100+ constexpr int RadParticleDeathTimeIdx = static_cast <int >(RadParticleRealIdx::death_time);
101+ constexpr int RadParticleLumIdx = static_cast <int >(RadParticleRealIdx::luminosity); // Base index for luminosity components
96102
97103// Number of real components for Rad_particles, birth time + death time + radiation groups
98104template <typename problem_t >
@@ -112,13 +118,19 @@ template <typename problem_t> using RadParticleIterator = amrex::ParIter<RadPart
112118
113119// -------------------- Gravitating particles --------------------
114120
115- // Indices for gravitating particles (CIC_particles), mass + 3 velocity components
116- enum CICParticleDataIdx {
117- CICParticleMassIdx = 0 , // Mass of the particle
118- CICParticleVxIdx, // Velocity in x direction
119- CICParticleVyIdx, // Velocity in y direction
120- CICParticleVzIdx // Velocity in z direction
121- };
121+ // Indices for gravitating particles (CIC_particles) using AMREX_ENUM for automatic string conversion
122+ AMREX_ENUM (CICParticleRealIdx, // NOLINT
123+ mass, // Mass of the particle
124+ vx, // Velocity in x direction
125+ vy, // Velocity in y direction
126+ vz // Velocity in z direction
127+ );
128+
129+ // Backward compatibility aliases for existing code
130+ constexpr int CICParticleMassIdx = static_cast <int >(CICParticleRealIdx::mass);
131+ constexpr int CICParticleVxIdx = static_cast <int >(CICParticleRealIdx::vx);
132+ constexpr int CICParticleVyIdx = static_cast <int >(CICParticleRealIdx::vy);
133+ constexpr int CICParticleVzIdx = static_cast <int >(CICParticleRealIdx::vz);
122134
123135// Number of real components for CIC_particles, mass + 3 velocity components
124136constexpr int CICParticleRealComps = 4 ;
@@ -129,16 +141,25 @@ using CICParticleIterator = amrex::ParIter<CICParticleRealComps>;
129141
130142// -------------------- Gravitating radiation particles --------------------
131143
132- // Indices for gravitating radiation particles (CICRad_particles), mass + 3 velocity components + birth time + death time + radiation groups
133- enum CICRadParticleDataIdx {
134- CICRadParticleMassIdx = 0 , // Mass of the particle
135- CICRadParticleVxIdx, // Velocity in x direction
136- CICRadParticleVyIdx, // Velocity in y direction
137- CICRadParticleVzIdx, // Velocity in z direction
138- CICRadParticleBirthTimeIdx, // Time when particle becomes active
139- CICRadParticleDeathTimeIdx, // Time when particle becomes inactive
140- CICRadParticleLumIdx // Base index for luminosity components
141- };
144+ // Indices for gravitating radiation particles (CICRad_particles) using AMREX_ENUM for automatic string conversion
145+ AMREX_ENUM (CICRadParticleRealIdx, // NOLINT
146+ mass, // Mass of the particle
147+ vx, // Velocity in x direction
148+ vy, // Velocity in y direction
149+ vz, // Velocity in z direction
150+ birth_time, // Time when particle becomes active
151+ death_time, // Time when particle becomes inactive
152+ luminosity // Base luminosity component (expanded to luminosity_0, luminosity_1, ... in I/O)
153+ );
154+
155+ // Backward compatibility aliases for existing code
156+ constexpr int CICRadParticleMassIdx = static_cast <int >(CICRadParticleRealIdx::mass);
157+ constexpr int CICRadParticleVxIdx = static_cast <int >(CICRadParticleRealIdx::vx);
158+ constexpr int CICRadParticleVyIdx = static_cast <int >(CICRadParticleRealIdx::vy);
159+ constexpr int CICRadParticleVzIdx = static_cast <int >(CICRadParticleRealIdx::vz);
160+ constexpr int CICRadParticleBirthTimeIdx = static_cast <int >(CICRadParticleRealIdx::birth_time);
161+ constexpr int CICRadParticleDeathTimeIdx = static_cast <int >(CICRadParticleRealIdx::death_time);
162+ constexpr int CICRadParticleLumIdx = static_cast <int >(CICRadParticleRealIdx::luminosity); // Base index for luminosity components
142163
143164// Number of real components for CICRad_particles, mass + 3 velocity components + birth time + death time + radiation groups
144165template <typename problem_t >
@@ -167,19 +188,33 @@ enum class StellarEvolutionStage { LowMassStar, SNProgenitor, SNRemnant, LowMass
167188
168189// -------------------- Stellar population particles --------------------
169190
170- // Indices for StochasticStellarPop_particles
171- enum StochasticStellarPopParticleDataIdx {
172- StochasticStellarPopParticleMassIdx = 0 , // Mass of the particle
173- StochasticStellarPopParticleVxIdx, // Velocity in x direction
174- StochasticStellarPopParticleVyIdx, // Velocity in y direction
175- StochasticStellarPopParticleVzIdx, // Velocity in z direction
176- StochasticStellarPopParticleBirthTimeIdx, // Time when particle becomes active
177- StochasticStellarPopParticleDeathTimeIdx, // Time when particle becomes inactive
178- StochasticStellarPopParticleMassAtBirthIdx, // Particle mass at birth
179- StochasticStellarPopParticleLumIdx // Base index for luminosity components
180- };
191+ // Indices for StochasticStellarPop_particles using AMREX_ENUM for automatic string conversion
192+ AMREX_ENUM (StochasticStellarPopParticleRealIdx, // NOLINT
193+ mass, // Mass of the particle
194+ vx, // Velocity in x direction
195+ vy, // Velocity in y direction
196+ vz, // Velocity in z direction
197+ birth_time, // Time when particle becomes active
198+ death_time, // Time when particle becomes inactive
199+ mass_at_birth, // Particle mass at birth
200+ luminosity // Base luminosity component (expanded to luminosity_0, luminosity_1, ... in I/O)
201+ );
202+
203+ // Integer component indices using AMREX_ENUM
204+ AMREX_ENUM (StochasticStellarPopParticleIntIdx, // NOLINT
205+ evolution_stage // Evolution stage of the particle
206+ );
181207
182- constexpr int StochasticStellarPopParticleStageIdx = 0 ; // Evolution stage of the particle, index in the integer components
208+ // Backward compatibility aliases for existing code
209+ constexpr int StochasticStellarPopParticleMassIdx = static_cast <int >(StochasticStellarPopParticleRealIdx::mass);
210+ constexpr int StochasticStellarPopParticleVxIdx = static_cast <int >(StochasticStellarPopParticleRealIdx::vx);
211+ constexpr int StochasticStellarPopParticleVyIdx = static_cast <int >(StochasticStellarPopParticleRealIdx::vy);
212+ constexpr int StochasticStellarPopParticleVzIdx = static_cast <int >(StochasticStellarPopParticleRealIdx::vz);
213+ constexpr int StochasticStellarPopParticleBirthTimeIdx = static_cast <int >(StochasticStellarPopParticleRealIdx::birth_time);
214+ constexpr int StochasticStellarPopParticleDeathTimeIdx = static_cast <int >(StochasticStellarPopParticleRealIdx::death_time);
215+ constexpr int StochasticStellarPopParticleMassAtBirthIdx = static_cast <int >(StochasticStellarPopParticleRealIdx::mass_at_birth);
216+ constexpr int StochasticStellarPopParticleLumIdx = static_cast <int >(StochasticStellarPopParticleRealIdx::luminosity); // Base index for luminosity components
217+ constexpr int StochasticStellarPopParticleStageIdx = static_cast <int >(StochasticStellarPopParticleIntIdx::evolution_stage);
183218
184219// Number of real components for StochasticStellarPop_particles, mass + 3 velocity components + luminosity
185220template <typename problem_t >
@@ -203,18 +238,32 @@ using StochasticStellarPopParticleIterator = amrex::ParIter<StochasticStellarPop
203238
204239// -------------------- Test particles --------------------
205240
206- // Indices for test particles (Test_particles)
207- enum TestParticleDataIdx {
208- TestParticleMassIdx = 0 , // Mass of the particle
209- TestParticleVxIdx, // Velocity in x direction
210- TestParticleVyIdx, // Velocity in y direction
211- TestParticleVzIdx, // Velocity in z direction
212- TestParticleBirthTimeIdx, // Time when particle becomes active
213- TestParticleDeathTimeIdx, // Time when particle becomes inactive
214- TestParticleLumIdx // Base index for luminosity components
215- };
241+ // Indices for test particles (Test_particles) using AMREX_ENUM for automatic string conversion
242+ // The enum values are short names that will appear directly in the Header file
243+ AMREX_ENUM (TestParticleRealIdx, // NOLINT
244+ mass, // Mass of the particle
245+ vx, // Velocity in x direction
246+ vy, // Velocity in y direction
247+ vz, // Velocity in z direction
248+ birth_time, // Time when particle becomes active
249+ death_time, // Time when particle becomes inactive
250+ luminosity // Base luminosity component (expanded to luminosity_0, luminosity_1, ... in I/O)
251+ );
216252
217- constexpr int TestParticleStageIdx = 0 ; // Evolution stage of the particle, index in the integer components
253+ // Integer component indices using AMREX_ENUM
254+ AMREX_ENUM (TestParticleIntIdx, // NOLINT
255+ evolution_stage // Evolution stage of the particle
256+ );
257+
258+ // Backward compatibility aliases for existing code
259+ constexpr int TestParticleMassIdx = static_cast <int >(TestParticleRealIdx::mass);
260+ constexpr int TestParticleVxIdx = static_cast <int >(TestParticleRealIdx::vx);
261+ constexpr int TestParticleVyIdx = static_cast <int >(TestParticleRealIdx::vy);
262+ constexpr int TestParticleVzIdx = static_cast <int >(TestParticleRealIdx::vz);
263+ constexpr int TestParticleBirthTimeIdx = static_cast <int >(TestParticleRealIdx::birth_time);
264+ constexpr int TestParticleDeathTimeIdx = static_cast <int >(TestParticleRealIdx::death_time);
265+ constexpr int TestParticleLumIdx = static_cast <int >(TestParticleRealIdx::luminosity); // Base index for luminosity components
266+ constexpr int TestParticleStageIdx = static_cast <int >(TestParticleIntIdx::evolution_stage);
218267
219268// Number of real components for Test_particles
220269template <typename problem_t >
@@ -235,13 +284,19 @@ template <typename problem_t> using TestParticleIterator = amrex::ParIter<TestPa
235284
236285// -------------------- Sink particles --------------------
237286
238- // Indices for Sink_particles
239- enum SinkParticleDataIdx {
240- SinkParticleMassIdx = 0 , // Mass of the particle
241- SinkParticleVxIdx, // Velocity in x direction
242- SinkParticleVyIdx, // Velocity in y direction
243- SinkParticleVzIdx, // Velocity in z direction
244- };
287+ // Indices for Sink_particles using AMREX_ENUM for automatic string conversion
288+ AMREX_ENUM (SinkParticleRealIdx, // NOLINT
289+ mass, // Mass of the particle
290+ vx, // Velocity in x direction
291+ vy, // Velocity in y direction
292+ vz // Velocity in z direction
293+ );
294+
295+ // Backward compatibility aliases for existing code
296+ constexpr int SinkParticleMassIdx = static_cast <int >(SinkParticleRealIdx::mass);
297+ constexpr int SinkParticleVxIdx = static_cast <int >(SinkParticleRealIdx::vx);
298+ constexpr int SinkParticleVyIdx = static_cast <int >(SinkParticleRealIdx::vy);
299+ constexpr int SinkParticleVzIdx = static_cast <int >(SinkParticleRealIdx::vz);
245300
246301// Number of real components for Sink_particles
247302constexpr int SinkParticleRealComps = 4 ; // mass, vx, vy, vz
@@ -252,6 +307,92 @@ using SinkParticleIterator = amrex::ParIter<SinkParticleRealComps>;
252307
253308#endif // AMREX_SPACEDIM == 3
254309
310+ // -------------------- Component Names for I/O --------------------
311+
312+ // Helper function to generate component names from an enum type
313+ // If expandLast is true, the last enum component is expanded with _0, _1, ... suffixes
314+ // to fill up to nComps total components
315+ template <typename EnumType, int nComps, bool expandLast> auto expandEnumNames () -> amrex::Vector<std::string>
316+ {
317+ const std::vector<std::string> enum_names = amrex::getEnumNameStrings<EnumType>();
318+ const auto enum_size = static_cast <int >(enum_names.size ());
319+ amrex::Vector<std::string> names;
320+
321+ if constexpr (nComps <= 0 ) {
322+ return names;
323+ }
324+
325+ if constexpr (!expandLast) {
326+ // No expansion - use enum names directly
327+ return {enum_names.begin (), enum_names.end ()};
328+ }
329+
330+ // Add all components except the last one
331+ for (int i = 0 ; i < enum_size - 1 ; ++i) {
332+ names.push_back (enum_names[i]);
333+ }
334+
335+ // Expand the last component into name_0, name_1, ...
336+ const std::string &base_name = enum_names.back ();
337+ const int nExtra = nComps - enum_size + 1 ;
338+ for (int i = 0 ; i < nExtra; ++i) {
339+ names.push_back (base_name + " _" + std::to_string (i));
340+ }
341+
342+ return names;
343+ }
344+
345+ // Unified template function to get real component names for any particle type
346+ // Uses AMREX_ENUM's getEnumNameStrings() and expands the last component for particle types with luminosity
347+ template <ParticleType particleType, typename problem_t > auto getParticleRealCompNames () -> amrex::Vector<std::string>
348+ {
349+ if constexpr (particleType == ParticleType::Rad) {
350+ return expandEnumNames<RadParticleRealIdx, RadParticleRealComps<problem_t >, true >();
351+ }
352+ #if AMREX_SPACEDIM == 3
353+ else if constexpr (particleType == ParticleType::CIC) {
354+ return expandEnumNames<CICParticleRealIdx, CICParticleRealComps, false >();
355+ } else if constexpr (particleType == ParticleType::CICRad) {
356+ return expandEnumNames<CICRadParticleRealIdx, CICRadParticleRealComps<problem_t >, true >();
357+ } else if constexpr (particleType == ParticleType::StochasticStellarPop) {
358+ return expandEnumNames<StochasticStellarPopParticleRealIdx, StochasticStellarPopParticleRealComps<problem_t >, true >();
359+ } else if constexpr (particleType == ParticleType::Sink) {
360+ return expandEnumNames<SinkParticleRealIdx, SinkParticleRealComps, false >();
361+ } else if constexpr (particleType == ParticleType::Test) {
362+ return expandEnumNames<TestParticleRealIdx, TestParticleRealComps<problem_t >, true >();
363+ }
364+ #endif
365+ else {
366+ return {};
367+ }
368+ }
369+
370+ // Unified template function to get integer component names for any particle type
371+ template <ParticleType particleType, typename problem_t > auto getParticleIntCompNames () -> amrex::Vector<std::string>
372+ {
373+ amrex::Vector<std::string> names;
374+
375+ if constexpr (particleType == ParticleType::Rad) { // NOLINT
376+ // No integer components
377+ }
378+ #if AMREX_SPACEDIM == 3
379+ else if constexpr (particleType == ParticleType::CIC) { // NOLINT
380+ // No integer components
381+ } else if constexpr (particleType == ParticleType::CICRad) { // NOLINT
382+ // No integer components
383+ } else if constexpr (particleType == ParticleType::StochasticStellarPop) {
384+ const std::vector<std::string> enum_names = amrex::getEnumNameStrings<StochasticStellarPopParticleIntIdx>();
385+ names = {enum_names.begin (), enum_names.end ()};
386+ } else if constexpr (particleType == ParticleType::Sink) { // NOLINT
387+ // No integer components
388+ } else if constexpr (particleType == ParticleType::Test) {
389+ const std::vector<std::string> enum_names = amrex::getEnumNameStrings<TestParticleIntIdx>();
390+ names = {enum_names.begin (), enum_names.end ()};
391+ }
392+ #endif
393+ return names;
394+ }
395+
255396// -------------------- Units --------------------
256397
257398// Units data for each particle type as powers of Mass, Length, Time, Temperature
0 commit comments