From f62ec7ce25e119b597968c72a5d2232d3b717caf Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:17:41 -0500 Subject: [PATCH 01/22] +injector_base: InjectorBase, InjectorFromLambda --- src/include/injector_base.hxx | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/include/injector_base.hxx diff --git a/src/include/injector_base.hxx b/src/include/injector_base.hxx new file mode 100644 index 000000000..5eddfe9c2 --- /dev/null +++ b/src/include/injector_base.hxx @@ -0,0 +1,29 @@ +#pragma once + +template +struct InjectorBase +{ + using Mparticles = MPARTICLES; + using MfieldsState = MFIELDS_STATE; + + virtual void inject(Mparticles& mprts, MfieldsState& mflds) = 0; +}; + +template +struct InjectFromLambda : InjectorBase +{ + using Mparticles = MPARTICLES; + using MfieldsState = MFIELDS_STATE; + + InjectFromLambda(std::function lambda) + : lambda{lambda} + {} + + void inject(Mparticles& mprts, MfieldsState& mflds) override + { + return lambda(mprts, mflds); + } + +private: + std::function lambda; +}; From 496ad5cd1d6a2b33784cb7c44b03f2d1f7c114e4 Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:21:24 -0500 Subject: [PATCH 02/22] boundary_injector: inherit from InjectorBase --- src/include/boundary_injector.hxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/include/boundary_injector.hxx b/src/include/boundary_injector.hxx index 72f9dc4eb..28d956754 100644 --- a/src/include/boundary_injector.hxx +++ b/src/include/boundary_injector.hxx @@ -11,6 +11,7 @@ #include "setup_particles.hxx" #include "kg/VecRange.hxx" #include "../libpsc/psc_push_particles/inc_push.cxx" +#include "injector_base.hxx" /// @brief A particle generator for use with @ref BoundaryInjector. Samples /// particles from a (possibly shifted) Maxwellian distribution. @@ -62,6 +63,8 @@ private: /// `MfieldsState`, `Current`, `real_t`, etc. template class BoundaryInjector + : public InjectorBase { static const int INJECT_DIM_IDX_ = 1; @@ -82,6 +85,11 @@ public: prts_per_unit_density_{grid.norm.prts_per_unit_density} {} + void inject(Mparticles& mprts, MfieldsState& mflds) override + { + (*this)(mprts, mflds); + } + /// Injects particles at the lower y-bound as if there were a population of /// particles just beyond the edge. The imaginary particle population has unit /// density, and individual particles from that population are sampled using From 7a35b9505ee6ac1937b5c530082da1595b748fd1 Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:22:09 -0500 Subject: [PATCH 03/22] psc: have a list of InjectorBase ptrs --- src/include/psc.hxx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index 4b8a567f0..5cf5f02b0 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -8,6 +8,7 @@ #include #include "../libpsc/vpic/fields_item_vpic.hxx" +#include "injector_base.hxx" #include #include #include @@ -343,7 +344,9 @@ struct Psc // === particle injection prof_start(pr_inject_prts); - inject_particles_(mprts_, mflds_); + for (auto injector : injectors) { + injector->inject(mprts_, mflds_); + } prof_stop(pr_inject_prts); // === external current @@ -470,6 +473,8 @@ private: public: const Grid_t& grid() { return *grid_; } + std::vector*> injectors; + private: double time_start_; PscParams p_; From a175f1348f8c15bb326990676114d2090cf8bd74 Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:23:43 -0500 Subject: [PATCH 04/22] *: add injectors to the list --- src/libpsc/tests/test_boundary_injector.cxx | 33 +++++++++++---------- src/psc_2d_shock.cxx | 9 ++++-- src/psc_flatfoil_yz.cxx | 9 ++++-- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/libpsc/tests/test_boundary_injector.cxx b/src/libpsc/tests/test_boundary_injector.cxx index ef51fd70f..e7816cb64 100644 --- a/src/libpsc/tests/test_boundary_injector.cxx +++ b/src/libpsc/tests/test_boundary_injector.cxx @@ -142,13 +142,13 @@ TEST(BoundaryInjectorTest, Integration1Particle) DiagEnergies oute{grid.comm(), 0}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - auto inject_particles = - BoundaryInjector{ - ParticleGenerator(1, 1), grid}; + auto psc = + makePscIntegrator(psc_params, grid, mflds, mprts, balance, + collision, checks, marder, diagnostics); - auto psc = makePscIntegrator(psc_params, grid, mflds, mprts, - balance, collision, checks, marder, - diagnostics, inject_particles); + psc.injectors.push_back( + new BoundaryInjector( + ParticleGenerator(1, 1), grid)); // ---------------------------------------------------------------------- // set up initial conditions @@ -205,13 +205,13 @@ TEST(BoundaryInjectorTest, IntegrationManyParticles) DiagEnergies oute{grid.comm(), 0}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - auto inject_particles = - BoundaryInjector{ - ParticleGenerator(-1, 1), grid}; + auto psc = + makePscIntegrator(psc_params, grid, mflds, mprts, balance, + collision, checks, marder, diagnostics); - auto psc = makePscIntegrator(psc_params, grid, mflds, mprts, - balance, collision, checks, marder, - diagnostics, inject_particles); + psc.injectors.push_back( + new BoundaryInjector( + ParticleGenerator(-1, 1), grid)); // ---------------------------------------------------------------------- // set up initial conditions @@ -275,11 +275,12 @@ TEST(BoundaryInjectorTest, IntegrationManySpecies) BoundaryInjector{ ParticleGenerator(-1, 1), grid}; - auto inject = make_composite(inject_electrons, inject_ions); + auto psc = + makePscIntegrator(psc_params, grid, mflds, mprts, balance, + collision, checks, marder, diagnostics); - auto psc = makePscIntegrator(psc_params, grid, mflds, mprts, - balance, collision, checks, marder, - diagnostics, inject); + psc.injectors.push_back(&inject_ions); + psc.injectors.push_back(&inject_electrons); // ---------------------------------------------------------------------- // set up initial conditions diff --git a/src/psc_2d_shock.cxx b/src/psc_2d_shock.cxx index 97d72c4d1..a54e529a4 100644 --- a/src/psc_2d_shock.cxx +++ b/src/psc_2d_shock.cxx @@ -608,9 +608,12 @@ void run() // ---------------------------------------------------------------------- // hand off to PscIntegrator to run the simulation - auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, - balance, collision, checks, marder, - diagnostics, lf_inject_heat); + auto psc = + makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, + collision, checks, marder, diagnostics); + + psc.injectors.push_back( + new InjectFromLambda(lf_inject_heat)); psc.integrate(); } diff --git a/src/psc_flatfoil_yz.cxx b/src/psc_flatfoil_yz.cxx index f2de74e21..ab29d5922 100644 --- a/src/psc_flatfoil_yz.cxx +++ b/src/psc_flatfoil_yz.cxx @@ -679,9 +679,12 @@ void run() // ---------------------------------------------------------------------- // hand off to PscIntegrator to run the simulation - auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, - balance, collision, checks, marder, - diagnostics, lf_inject_heat); + auto psc = + makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, + collision, checks, marder, diagnostics); + + psc.injectors.push_back( + new InjectFromLambda(lf_inject_heat)); MEM_STATS(); psc.integrate(); From 99beaf19a08369b49f235c94fa2f6a849f1fdb22 Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:24:17 -0500 Subject: [PATCH 05/22] psc; *: rm templated injector --- src/include/psc.hxx | 20 ++++++-------------- src/psc_radiation.cxx | 6 +++--- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index 5cf5f02b0..d127b3d16 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -100,8 +100,7 @@ inline double courant_length(const Grid_t::Domain& domain) // ====================================================================== // Psc -template +template struct Psc { using Mparticles = typename PscConfig::Mparticles; @@ -123,8 +122,7 @@ struct Psc Psc(const PscParams& params, Grid_t& grid, MfieldsState& mflds, Mparticles& mprts, Balance& balance, Collision& collision, Checks& checks, - Marder& marder, Diagnostics& diagnostics, - InjectParticles& inject_particles, ExtCurrent& ext_current) + Marder& marder, Diagnostics& diagnostics, ExtCurrent& ext_current) : p_{params}, grid_{&grid}, mflds_{mflds}, @@ -135,7 +133,6 @@ struct Psc marder_{marder}, bndp_{grid}, diagnostics_{diagnostics}, - inject_particles_{inject_particles}, ext_current_{ext_current}, checkpointing_{params.write_checkpoint_every_step} { @@ -490,7 +487,6 @@ protected: Checks& checks_; Marder& marder_; Diagnostics& diagnostics_; - InjectParticles& inject_particles_; ExtCurrent& ext_current_; Sort sort_; @@ -553,18 +549,14 @@ ExtCurrentNone extCurrentNone; template -Psc makePscIntegrator( +Psc makePscIntegrator( const PscParams& params, Grid_t& grid, MfieldsState& mflds, Mparticles& mprts, Balance& balance, Collision& collision, Checks& checks, Marder& marder, - Diagnostics& diagnostics, - InjectParticles& inject_particles = injectParticlesNone, - ExtCurrent& ext_current = extCurrentNone) + Diagnostics& diagnostics, ExtCurrent& ext_current = extCurrentNone) { - return {params, grid, mflds, mprts, balance, - collision, checks, marder, diagnostics, inject_particles, - ext_current}; + return {params, grid, mflds, mprts, balance, + collision, checks, marder, diagnostics, ext_current}; } // ====================================================================== diff --git a/src/psc_radiation.cxx b/src/psc_radiation.cxx index 1f94a27f2..2c8073e77 100644 --- a/src/psc_radiation.cxx +++ b/src/psc_radiation.cxx @@ -304,9 +304,9 @@ void run() // ---------------------------------------------------------------------- // hand off to PscIntegrator to run the simulation - auto psc = makePscIntegrator( - psc_params, *grid_ptr, mflds, mprts, balance, collision, checks, marder, - diagnostics, injectParticlesNone, lf_ext_current); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder, + diagnostics, lf_ext_current); MEM_STATS(); psc.integrate(); From 1be2d528e447f105ddaa37e656e2d809dfa8a971 Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:25:42 -0500 Subject: [PATCH 06/22] psc: -InjectParticlesNone --- src/include/psc.hxx | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index d127b3d16..ca4e99ce3 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -508,24 +508,6 @@ protected: int st_time_step; }; -// ====================================================================== -// InjectParticlesNone - -class InjectParticlesNone -{ -public: - template - void operator()(Mparticles& mprts, MfieldsState& mflds) - {} -}; - -namespace -{ - -InjectParticlesNone injectParticlesNone; - -} // namespace - // ====================================================================== // ExtCurrentNone From 1c2ddfbab3e15d5326b8668026e77d13b2e86699 Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:29:11 -0500 Subject: [PATCH 07/22] -composite_injector; * --- src/include/boundary_injector.hxx | 2 +- src/include/composite_injector.hxx | 48 --------------------- src/libpsc/tests/test_boundary_injector.cxx | 1 - 3 files changed, 1 insertion(+), 50 deletions(-) delete mode 100644 src/include/composite_injector.hxx diff --git a/src/include/boundary_injector.hxx b/src/include/boundary_injector.hxx index 28d956754..520297754 100644 --- a/src/include/boundary_injector.hxx +++ b/src/include/boundary_injector.hxx @@ -55,7 +55,7 @@ private: /// @brief Injects particles on a given boundary, sampling from a given particle /// generator. For precise control over multiple particle species, use one -/// BoundaryInjector per species, combined with @ref CompositeInjector. +/// BoundaryInjector per species. /// @tparam PARTICLE_GENERATOR a type that defines `get(min_pos, pos_range)` and /// returns an injectable particle within that range of positions (usually a /// grid cell); see @ref ParticleGeneratorMaxwellian diff --git a/src/include/composite_injector.hxx b/src/include/composite_injector.hxx deleted file mode 100644 index 105c605bf..000000000 --- a/src/include/composite_injector.hxx +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -/// @brief An injector comprising two other injectors. Enables multiple -/// injectors in a single psc case. Useful for injecting multiple species with -/// @ref BoundaryInjector. -/// @tparam INJECTOR_1 first type of injector -/// @tparam INJECTOR_2 second type of injector -template -class CompositeInjector -{ -public: - using Mparticles = typename INJECTOR_1::Mparticles; - using MfieldsState = typename INJECTOR_1::MfieldsState; - - CompositeInjector(INJECTOR_1 injector_1, INJECTOR_2 injector_2) - : injector_1{injector_1}, injector_2{injector_2} - {} - - /// @brief Calls both member injectors in order. - /// @param mprts particles - /// @param mflds fields - void operator()(Mparticles& mprts, MfieldsState& mflds) - { - injector_1(mprts, mflds); - injector_2(mprts, mflds); - } - -private: - INJECTOR_1 injector_1; - INJECTOR_2 injector_2; -}; - -/// @brief Helper method to deduce the type of a composite injector, enabling -/// e.g. `auto composite_injector = make_composite(injector_1, injector_2);` -/// -/// Wouldn't be necessary in C++17; see -/// https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rt-deduce. -/// @tparam INJECTOR_1 first type of injector -/// @tparam INJECTOR_2 second type of injector -/// @param injector_1 first injector -/// @param injector_2 second injector -/// @return -template -CompositeInjector make_composite(INJECTOR_1 injector_1, - INJECTOR_2 injector_2) -{ - return CompositeInjector(injector_1, injector_2); -} diff --git a/src/libpsc/tests/test_boundary_injector.cxx b/src/libpsc/tests/test_boundary_injector.cxx index e7816cb64..6f5556fc4 100644 --- a/src/libpsc/tests/test_boundary_injector.cxx +++ b/src/libpsc/tests/test_boundary_injector.cxx @@ -3,7 +3,6 @@ #include "test_common.hxx" #include "boundary_injector.hxx" -#include "composite_injector.hxx" #include "psc.hxx" #include "DiagnosticsDefault.h" From 3931fad94fe6c21da695cace94daa37af00b84ae Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:41:17 -0500 Subject: [PATCH 08/22] +external_current_base --- src/include/external_current_base.hxx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/include/external_current_base.hxx diff --git a/src/include/external_current_base.hxx b/src/include/external_current_base.hxx new file mode 100644 index 000000000..48242f79e --- /dev/null +++ b/src/include/external_current_base.hxx @@ -0,0 +1,24 @@ +#pragma once + +template +struct ExternalCurrentBase +{ + using MfieldsState = MFIELDS_STATE; + + virtual void inject_current(MfieldsState& mflds) = 0; +}; + +template +struct ExternalCurrentFromLambda : ExternalCurrentBase +{ + using MfieldsState = MFIELDS_STATE; + + ExternalCurrentFromLambda(std::function lambda) + : lambda{lambda} + {} + + void inject_current(MfieldsState& mflds) override { return lambda(mflds); } + +private: + std::function lambda; +}; From 0e6f2a502bc6340a1e3e57fed1dee59c41392473 Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:41:34 -0500 Subject: [PATCH 09/22] psc; *: use vec of ExternalCurrents --- src/include/psc.hxx | 23 ++++++++++++----------- src/psc_radiation.cxx | 14 +++++++++----- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index ca4e99ce3..0aaf3941c 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -9,6 +9,7 @@ #include "../libpsc/vpic/fields_item_vpic.hxx" #include "injector_base.hxx" +#include "external_current_base.hxx" #include #include #include @@ -100,7 +101,7 @@ inline double courant_length(const Grid_t::Domain& domain) // ====================================================================== // Psc -template +template struct Psc { using Mparticles = typename PscConfig::Mparticles; @@ -122,7 +123,7 @@ struct Psc Psc(const PscParams& params, Grid_t& grid, MfieldsState& mflds, Mparticles& mprts, Balance& balance, Collision& collision, Checks& checks, - Marder& marder, Diagnostics& diagnostics, ExtCurrent& ext_current) + Marder& marder, Diagnostics& diagnostics) : p_{params}, grid_{&grid}, mflds_{mflds}, @@ -133,7 +134,6 @@ struct Psc marder_{marder}, bndp_{grid}, diagnostics_{diagnostics}, - ext_current_{ext_current}, checkpointing_{params.write_checkpoint_every_step} { time_start_ = MPI_Wtime(); @@ -348,7 +348,9 @@ struct Psc // === external current prof_start(pr_external_current); - this->ext_current_(grid(), mflds_); + for (auto external_current : external_currents) { + external_current->inject_current(mflds_); + } prof_stop(pr_external_current); mpi_printf(comm, "***** Bnd particles...\n"); @@ -471,6 +473,7 @@ public: const Grid_t& grid() { return *grid_; } std::vector*> injectors; + std::vector*> external_currents; private: double time_start_; @@ -487,7 +490,6 @@ protected: Checks& checks_; Marder& marder_; Diagnostics& diagnostics_; - ExtCurrent& ext_current_; Sort sort_; PushParticles pushp_; @@ -530,15 +532,14 @@ ExtCurrentNone extCurrentNone; template -Psc makePscIntegrator( + typename Marder, typename Diagnostics> +Psc makePscIntegrator( const PscParams& params, Grid_t& grid, MfieldsState& mflds, Mparticles& mprts, Balance& balance, Collision& collision, Checks& checks, Marder& marder, - Diagnostics& diagnostics, ExtCurrent& ext_current = extCurrentNone) + Diagnostics& diagnostics) { - return {params, grid, mflds, mprts, balance, - collision, checks, marder, diagnostics, ext_current}; + return {params, grid, mflds, mprts, balance, + collision, checks, marder, diagnostics}; } // ====================================================================== diff --git a/src/psc_radiation.cxx b/src/psc_radiation.cxx index 2c8073e77..fdd75c4bc 100644 --- a/src/psc_radiation.cxx +++ b/src/psc_radiation.cxx @@ -234,7 +234,8 @@ void run() psc_params.marder_interval = -1; Marder marder(grid, marder_diffusion, marder_loop, marder_dump); - auto lf_ext_current = [&](const Grid_t& grid, MfieldsState& mflds) { + auto lf_ext_current = [&](MfieldsState& mflds) { + const Grid_t& grid = mflds.grid(); double time = grid.time(); auto& gdims = grid.domain.gdims; for (int p = 0; p < mflds.n_patches(); ++p) { @@ -298,15 +299,18 @@ void run() if (read_checkpoint_filename.empty()) { initializeFields(mflds); - lf_ext_current(*grid_ptr, mflds); + lf_ext_current(mflds); } // ---------------------------------------------------------------------- // hand off to PscIntegrator to run the simulation - auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, - balance, collision, checks, marder, - diagnostics, lf_ext_current); + auto psc = + makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, + collision, checks, marder, diagnostics); + + psc.external_currents.push_back( + new ExternalCurrentFromLambda(lf_ext_current)); MEM_STATS(); psc.integrate(); From ddc197a0427f0df1696062209d79335c877687f8 Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:41:50 -0500 Subject: [PATCH 10/22] psc: -ExternalCurrentNone --- src/include/psc.hxx | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index 0aaf3941c..e40366dbb 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -510,23 +510,6 @@ protected: int st_time_step; }; -// ====================================================================== -// ExtCurrentNone - -class ExtCurrentNone -{ -public: - template - void operator()(const Grid_t& grid, MfieldsState& mflds) - {} -}; - -namespace -{ - -ExtCurrentNone extCurrentNone; - -} // namespace // ====================================================================== // makePscIntegrator From bc43fb19cc9292baf2ea99c6ac5c968f1c9d1618 Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 15:56:04 -0500 Subject: [PATCH 11/22] psc; *: make vecs private --- src/include/psc.hxx | 28 +++++++++++++++++---- src/libpsc/tests/test_boundary_injector.cxx | 8 +++--- src/psc_2d_shock.cxx | 2 +- src/psc_flatfoil_yz.cxx | 2 +- src/psc_radiation.cxx | 2 +- 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index e40366dbb..632f36263 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -117,6 +117,8 @@ struct Psc using BndFields = typename PscConfig::BndFields; using BndParticles = typename PscConfig::BndParticles; using Dim = typename PscConfig::Dim; + using InjectorBaseT = InjectorBase; + using ExternalCurrentBaseT = ExternalCurrentBase; // ---------------------------------------------------------------------- // ctor @@ -157,6 +159,23 @@ struct Psc initialize(); } + // ---------------------------------------------------------------------- + // API for modifying various internal components + + void add_injector(InjectorBaseT* injector) + { + if (injector) { + injectors_.push_back(injector); + } + } + + void add_external_current(ExternalCurrentBaseT* external_current) + { + if (external_current) { + external_currents_.push_back(external_current); + } + } + // ---------------------------------------------------------------------- // initialize_stats @@ -341,14 +360,14 @@ struct Psc // === particle injection prof_start(pr_inject_prts); - for (auto injector : injectors) { + for (auto injector : injectors_) { injector->inject(mprts_, mflds_); } prof_stop(pr_inject_prts); // === external current prof_start(pr_external_current); - for (auto external_current : external_currents) { + for (auto external_current : external_currents_) { external_current->inject_current(mflds_); } prof_stop(pr_external_current); @@ -472,9 +491,6 @@ private: public: const Grid_t& grid() { return *grid_; } - std::vector*> injectors; - std::vector*> external_currents; - private: double time_start_; PscParams p_; @@ -490,6 +506,8 @@ protected: Checks& checks_; Marder& marder_; Diagnostics& diagnostics_; + std::vector injectors_; + std::vector external_currents_; Sort sort_; PushParticles pushp_; diff --git a/src/libpsc/tests/test_boundary_injector.cxx b/src/libpsc/tests/test_boundary_injector.cxx index 6f5556fc4..95d99153d 100644 --- a/src/libpsc/tests/test_boundary_injector.cxx +++ b/src/libpsc/tests/test_boundary_injector.cxx @@ -145,7 +145,7 @@ TEST(BoundaryInjectorTest, Integration1Particle) makePscIntegrator(psc_params, grid, mflds, mprts, balance, collision, checks, marder, diagnostics); - psc.injectors.push_back( + psc.add_injector( new BoundaryInjector( ParticleGenerator(1, 1), grid)); @@ -208,7 +208,7 @@ TEST(BoundaryInjectorTest, IntegrationManyParticles) makePscIntegrator(psc_params, grid, mflds, mprts, balance, collision, checks, marder, diagnostics); - psc.injectors.push_back( + psc.add_injector( new BoundaryInjector( ParticleGenerator(-1, 1), grid)); @@ -278,8 +278,8 @@ TEST(BoundaryInjectorTest, IntegrationManySpecies) makePscIntegrator(psc_params, grid, mflds, mprts, balance, collision, checks, marder, diagnostics); - psc.injectors.push_back(&inject_ions); - psc.injectors.push_back(&inject_electrons); + psc.add_injector(&inject_ions); + psc.add_injector(&inject_electrons); // ---------------------------------------------------------------------- // set up initial conditions diff --git a/src/psc_2d_shock.cxx b/src/psc_2d_shock.cxx index a54e529a4..ca3a27ad5 100644 --- a/src/psc_2d_shock.cxx +++ b/src/psc_2d_shock.cxx @@ -612,7 +612,7 @@ void run() makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, collision, checks, marder, diagnostics); - psc.injectors.push_back( + psc.add_injector( new InjectFromLambda(lf_inject_heat)); psc.integrate(); diff --git a/src/psc_flatfoil_yz.cxx b/src/psc_flatfoil_yz.cxx index ab29d5922..c61d59d0b 100644 --- a/src/psc_flatfoil_yz.cxx +++ b/src/psc_flatfoil_yz.cxx @@ -683,7 +683,7 @@ void run() makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, collision, checks, marder, diagnostics); - psc.injectors.push_back( + psc.add_injector( new InjectFromLambda(lf_inject_heat)); MEM_STATS(); diff --git a/src/psc_radiation.cxx b/src/psc_radiation.cxx index fdd75c4bc..898fb7d1f 100644 --- a/src/psc_radiation.cxx +++ b/src/psc_radiation.cxx @@ -309,7 +309,7 @@ void run() makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, collision, checks, marder, diagnostics); - psc.external_currents.push_back( + psc.add_external_current( new ExternalCurrentFromLambda(lf_ext_current)); MEM_STATS(); From 358a042a7ef40e74d825a7acb86c71c66751fbef Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 16:12:57 -0500 Subject: [PATCH 12/22] boundary_injector: don't impl op() --- src/include/boundary_injector.hxx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/include/boundary_injector.hxx b/src/include/boundary_injector.hxx index 520297754..3f8632457 100644 --- a/src/include/boundary_injector.hxx +++ b/src/include/boundary_injector.hxx @@ -85,18 +85,13 @@ public: prts_per_unit_density_{grid.norm.prts_per_unit_density} {} - void inject(Mparticles& mprts, MfieldsState& mflds) override - { - (*this)(mprts, mflds); - } - /// Injects particles at the lower y-bound as if there were a population of /// particles just beyond the edge. The imaginary particle population has unit /// density, and individual particles from that population are sampled using /// the given ParticleGenerator. /// /// Some of these limitations may be removed in the future. - void operator()(Mparticles& mprts, MfieldsState& mflds) + void inject(Mparticles& mprts, MfieldsState& mflds) override { static_assert(INJECT_DIM_IDX_ == 1, "only injection at lower bound of y is supported"); From c3fbc686a2eca0886f506dd22cc52a95705dd5fb Mon Sep 17 00:00:00 2001 From: James McClung Date: Fri, 23 Jan 2026 16:39:18 -0500 Subject: [PATCH 13/22] psc; *: initialize -> pre_first_step --- src/include/psc.hxx | 27 ++++++++++--------- src/libpsc/tests/test_boundary_injector.cxx | 3 +++ .../tests/test_open_bcs_integration.cxx | 1 + .../tests/test_reflective_bcs_integration.cxx | 2 ++ 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index 632f36263..e3f2854fd 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -156,7 +156,6 @@ struct Psc #endif initialize_stats(); - initialize(); } // ---------------------------------------------------------------------- @@ -195,9 +194,9 @@ struct Psc } // ---------------------------------------------------------------------- - // initialize + // pre_first_step - void initialize() + void pre_first_step() { bndf_.fill_ghosts_H(mflds_); bnd_.fill_ghosts(mflds_, HX, HX + 3); @@ -215,16 +214,6 @@ struct Psc mpi_printf(grid().comm(), "Checking gauss.\n"); checks_.gauss(mprts_, mflds_); } - - // initial output / stats - mpi_printf(grid().comm(), "Performing initial diagnostics.\n"); - diagnostics(); - - psc_stats_val[st_nr_particles] = mprts_.size(); - - print_status(); - - mpi_printf(grid().comm(), "Initialization complete.\n"); } // ---------------------------------------------------------------------- @@ -237,6 +226,18 @@ struct Psc pr = prof_register("psc_step", 1., 0, 0); } + pre_first_step(); + + // initial output / stats + mpi_printf(grid().comm(), "Performing initial diagnostics.\n"); + diagnostics(); + + psc_stats_val[st_nr_particles] = mprts_.size(); + + print_status(); + + mpi_printf(grid().comm(), "Initialization complete.\n"); + mpi_printf(grid().comm(), "*** Advancing\n"); double elapsed = MPI_Wtime(); diff --git a/src/libpsc/tests/test_boundary_injector.cxx b/src/libpsc/tests/test_boundary_injector.cxx index 95d99153d..37a02759e 100644 --- a/src/libpsc/tests/test_boundary_injector.cxx +++ b/src/libpsc/tests/test_boundary_injector.cxx @@ -163,6 +163,7 @@ TEST(BoundaryInjectorTest, Integration1Particle) ASSERT_EQ(prts.size(), 0); + psc.pre_first_step(); for (; grid.timestep_ < psc_params.nmax;) { psc.step(); @@ -226,6 +227,7 @@ TEST(BoundaryInjectorTest, IntegrationManyParticles) ASSERT_EQ(prts.size(), 0); + psc.pre_first_step(); for (; grid.timestep_ < psc_params.nmax;) { psc.step(); @@ -295,6 +297,7 @@ TEST(BoundaryInjectorTest, IntegrationManySpecies) ASSERT_EQ(prts.size(), 0); + psc.pre_first_step(); for (; grid.timestep_ < psc_params.nmax;) { psc.step(); diff --git a/src/libpsc/tests/test_open_bcs_integration.cxx b/src/libpsc/tests/test_open_bcs_integration.cxx index 92e36fcde..71feedceb 100644 --- a/src/libpsc/tests/test_open_bcs_integration.cxx +++ b/src/libpsc/tests/test_open_bcs_integration.cxx @@ -148,6 +148,7 @@ TEST(OpenBcsTest, IntegrationY) ASSERT_EQ(prts[0].q(), -1.0); ASSERT_EQ(prts[1].q(), 1.0); + psc.pre_first_step(); for (; grid.timestep_ < psc_params.nmax;) { psc.step(); ASSERT_LT(checks.continuity.last_max_err, checks.continuity.err_threshold); diff --git a/src/libpsc/tests/test_reflective_bcs_integration.cxx b/src/libpsc/tests/test_reflective_bcs_integration.cxx index 5068be256..e78984163 100644 --- a/src/libpsc/tests/test_reflective_bcs_integration.cxx +++ b/src/libpsc/tests/test_reflective_bcs_integration.cxx @@ -141,6 +141,7 @@ TEST(ReflectiveBcsTest, IntegrationY) bool about_to_reflect = false; bool reflected = false; + psc.pre_first_step(); for (; grid.timestep_ < psc_params.nmax;) { about_to_reflect = prts[0].x()[1] < grid.domain.dx[1] && prts[0].u()[1] < 0.0; @@ -228,6 +229,7 @@ TEST(ReflectiveBcsTest, IntegrationZ) bool about_to_reflect = false; bool reflected = false; + psc.pre_first_step(); for (; grid.timestep_ < psc_params.nmax;) { about_to_reflect = prts[0].x()[2] < grid.domain.dx[2] && prts[0].u()[2] < 0.0; From f4a58a6eb76079e7cca0267f2ab3d3ace72d5ae9 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 27 Jan 2026 07:33:08 -0500 Subject: [PATCH 14/22] +diagnostic_base --- src/include/diagnostic_base.hxx | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/include/diagnostic_base.hxx diff --git a/src/include/diagnostic_base.hxx b/src/include/diagnostic_base.hxx new file mode 100644 index 000000000..df213f66b --- /dev/null +++ b/src/include/diagnostic_base.hxx @@ -0,0 +1,29 @@ +#pragma once + +template +struct DiagnosticBase +{ + virtual void perform_diagnostic(Mparticles& mprts, MfieldsState& mflds) = 0; +}; + +template +struct ParticleDiagnosticBase +{ + virtual void perform_diagnostic(Mparticles& mprts) = 0; +}; + +template +struct DiagnosticFromLambda : public DiagnosticBase +{ + DiagnosticFromLambda(std::function lambda) + : lambda{lambda} + {} + + void perform_diagnostic(Mparticles& mprts, MfieldsState& mflds) override + { + return lambda(mprts, mflds); + } + +private: + std::function lambda; +}; From 7ee609c0b07d915b1ecc25903316e3fdd8d433d4 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 27 Jan 2026 07:38:29 -0500 Subject: [PATCH 15/22] OutputFieldsDefault: make diagnostic --- src/include/OutputFieldsDefault.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/include/OutputFieldsDefault.h b/src/include/OutputFieldsDefault.h index 0d76bd537..eafc7b588 100644 --- a/src/include/OutputFieldsDefault.h +++ b/src/include/OutputFieldsDefault.h @@ -1,6 +1,7 @@ #pragma once +#include "diagnostic_base.hxx" #include "../libpsc/psc_output_fields/fields_item_fields.hxx" #include "../libpsc/psc_output_fields/fields_item_moments_1st.hxx" #ifdef USE_CUDA @@ -242,7 +243,7 @@ struct OutputFieldsParams template -class OutputFields +class OutputFields : public DiagnosticBase { public: // ---------------------------------------------------------------------- @@ -252,6 +253,11 @@ class OutputFields : fields{grid, prm.fields, ""}, moments{grid, prm.moments, "_moments"} {} + void perform_diagnostic(Mparticles& mprts, MfieldsState& mflds) override + { + (*this)(mflds, mprts); + } + // ---------------------------------------------------------------------- // operator() From dceac220971171048c6addae5f420242aa5163db Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 27 Jan 2026 07:45:30 -0500 Subject: [PATCH 16/22] output_particles*; *: make diagnostic --- .../output_particles_ascii_impl.hxx | 7 +++++-- .../output_particles_hdf5_impl.hxx | 10 +++++++--- src/libpsc/tests/test_output_particles.cxx | 8 +++++--- src/psc_config.hxx | 10 ++++++---- src/psc_flatfoil_yz.cxx | 3 ++- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/libpsc/psc_output_particles/output_particles_ascii_impl.hxx b/src/libpsc/psc_output_particles/output_particles_ascii_impl.hxx index 406825fab..760005a93 100644 --- a/src/libpsc/psc_output_particles/output_particles_ascii_impl.hxx +++ b/src/libpsc/psc_output_particles/output_particles_ascii_impl.hxx @@ -1,18 +1,21 @@ - +#include "diagnostic_base.hxx" #include "output_particles.hxx" +template struct OutputParticlesAscii : OutputParticlesParams , OutputParticlesBase + , public ParticleDiagnosticBase { OutputParticlesAscii(const Grid_t& grid, const OutputParticlesParams& params) : OutputParticlesParams(params), comm_{grid.comm()} {} + void perform_diagnostic(Mparticles& mprts) override { (*this)(mprts); } + // ---------------------------------------------------------------------- // operator() - template void operator()(Mparticles& mprts) { const auto& grid = mprts.grid(); diff --git a/src/libpsc/psc_output_particles/output_particles_hdf5_impl.hxx b/src/libpsc/psc_output_particles/output_particles_hdf5_impl.hxx index 1417bfd67..a698a0b7d 100644 --- a/src/libpsc/psc_output_particles/output_particles_hdf5_impl.hxx +++ b/src/libpsc/psc_output_particles/output_particles_hdf5_impl.hxx @@ -8,6 +8,7 @@ #include "grid.hxx" #include "output_particles.hxx" +#include "diagnostic_base.hxx" #include "psc_particles_single.h" #include "../libpsc/vpic/mparticles_vpic.hxx" @@ -758,8 +759,10 @@ private: } // namespace detail -template -class OutputParticlesHdf5 : OutputParticlesBase +template +class OutputParticlesHdf5 + : OutputParticlesBase + , public ParticleDiagnosticBase { static OutputParticlesParams adjust_params( const OutputParticlesParams& params_in, const Grid_t& grid) @@ -781,7 +784,8 @@ public: writer_{params_, grid.kinds, grid.comm()} {} - template + void perform_diagnostic(Mparticles& mprts) override { (*this)(mprts); } + void operator()(Mparticles& mprts) { const auto& grid = mprts.grid(); diff --git a/src/libpsc/tests/test_output_particles.cxx b/src/libpsc/tests/test_output_particles.cxx index ff68aa077..19e5523c3 100644 --- a/src/libpsc/tests/test_output_particles.cxx +++ b/src/libpsc/tests/test_output_particles.cxx @@ -65,11 +65,13 @@ struct OutputParticlesTest : ::testing::Test }; using OutputParticlesTestTypes = ::testing::Types< - Config + Config> #ifdef H5_HAVE_PARALLEL , - Config>, - Config> + Config>, + Config> #endif >; diff --git a/src/psc_config.hxx b/src/psc_config.hxx index 9f1e40ac2..5e5ed4f88 100644 --- a/src/psc_config.hxx +++ b/src/psc_config.hxx @@ -31,7 +31,9 @@ #include "../libpsc/vpic/fields_item_vpic.hxx" -using OutputParticlesDefault = OutputParticlesHdf5; +template +using OutputParticlesDefault = + OutputParticlesHdf5; struct SimulationNone { @@ -94,7 +96,7 @@ struct PscConfig_ using Checks = Checks_; using Marder = Marder_; using Simulation = _Simulation; - using OutputParticles = OutputParticlesDefault; + using OutputParticles = OutputParticlesDefault; }; #ifdef USE_CUDA @@ -119,7 +121,7 @@ struct PscConfig_<_Dim, _Mparticles, _MfieldsState, _Mfields, using Balance = Balance_; using Checks = ChecksCuda; using Marder = MarderCuda; - using OutputParticles = OutputParticlesDefault; + using OutputParticles = OutputParticlesDefault; }; template @@ -143,7 +145,7 @@ struct PscConfig_; using Checks = ChecksCuda; using Marder = MarderCuda; - using OutputParticles = OutputParticlesDefault; + using OutputParticles = OutputParticlesDefault; }; #endif diff --git a/src/psc_flatfoil_yz.cxx b/src/psc_flatfoil_yz.cxx index c61d59d0b..f2832f164 100644 --- a/src/psc_flatfoil_yz.cxx +++ b/src/psc_flatfoil_yz.cxx @@ -227,7 +227,8 @@ using Collision = PscConfig::Collision; using Checks = PscConfig::Checks; using Marder = PscConfig::Marder; #if CASE == CASE_2D_SMALL -using OutputParticles = OutputParticlesHdf5>; +using OutputParticles = + OutputParticlesHdf5>; #else using OutputParticles = PscConfig::OutputParticles; #endif From ad808225f2afdb333b81a76d12b0a0fbc24bc34e Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 27 Jan 2026 07:50:55 -0500 Subject: [PATCH 17/22] DiagEnergies; *: make diagnostic --- src/include/DiagEnergies.h | 12 ++++++-- src/include/DiagEnergies.inl | 28 +++++++++++-------- src/libpsc/tests/test_boundary_injector.cxx | 6 ++-- .../tests/test_open_bcs_integration.cxx | 2 +- .../tests/test_reflective_bcs_integration.cxx | 4 +-- src/psc_2d_shock.cxx | 2 +- src/psc_bgk.cxx | 2 +- src/psc_bubble_yz.cxx | 2 +- src/psc_flatfoil_yz.cxx | 2 +- src/psc_harris_yz.cxx | 2 +- src/psc_radiation.cxx | 2 +- src/psc_shock.cxx | 2 +- src/psc_whistler.cxx | 2 +- 13 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/include/DiagEnergies.h b/src/include/DiagEnergies.h index 67a5037b6..bbd72dc6c 100644 --- a/src/include/DiagEnergies.h +++ b/src/include/DiagEnergies.h @@ -3,23 +3,29 @@ #include "DiagEnergiesField.h" #include "DiagEnergiesParticle.h" +#include "diagnostic_base.hxx" #include "psc.h" -class DiagEnergies +template +class DiagEnergies : public DiagnosticBase { public: DiagEnergies(); DiagEnergies(MPI_Comm comm, int interval); - template + void perform_diagnostic(Mparticles& mprts, MfieldsState& mflds) + { + (*this)(mprts, mflds); + } + void operator()(Mparticles& mprts, MfieldsState& mflds); private: template static std::string legend(const Item& item); - template + template void write_one(const Item& item, Mparticles& mprts, MfieldsState& mflds); private: diff --git a/src/include/DiagEnergies.inl b/src/include/DiagEnergies.inl index 7a81a0ecd..25c660ab8 100644 --- a/src/include/DiagEnergies.inl +++ b/src/include/DiagEnergies.inl @@ -2,19 +2,21 @@ namespace { -void fclose_helper(FILE* fp) -{ - ::fclose(fp); -} +void fclose_helper(FILE* fp) { ::fclose(fp); } } // namespace // ---------------------------------------------------------------------- // DiagEnergies ctors -inline DiagEnergies::DiagEnergies() : file_{nullptr, fclose_helper} {} +template +inline DiagEnergies::DiagEnergies() + : file_{nullptr, fclose_helper} +{} -inline DiagEnergies::DiagEnergies(MPI_Comm comm, int interval) +template +inline DiagEnergies::DiagEnergies(MPI_Comm comm, + int interval) : comm_{comm}, interval_{interval}, file_{nullptr, fclose_helper} { MPI_Comm_rank(comm_, &rank_); @@ -32,7 +34,8 @@ inline DiagEnergies::DiagEnergies(MPI_Comm comm, int interval) // DiagEnergies::operator() template -inline void DiagEnergies::operator()(Mparticles& mprts, MfieldsState& mflds) +inline void DiagEnergies::operator()( + Mparticles& mprts, MfieldsState& mflds) { const auto& grid = mprts.grid(); @@ -56,8 +59,10 @@ inline void DiagEnergies::operator()(Mparticles& mprts, MfieldsState& mflds) // ---------------------------------------------------------------------- // legend +template template -inline std::string DiagEnergies::legend(const Item& item) +inline std::string DiagEnergies::legend( + const Item& item) { std::string s; for (auto& name : item.names()) { @@ -69,9 +74,10 @@ inline std::string DiagEnergies::legend(const Item& item) // ---------------------------------------------------------------------- // write_one -template -inline void DiagEnergies::write_one(const Item& item, Mparticles& mprts, - MfieldsState& mflds) +template +template +inline void DiagEnergies::write_one( + const Item& item, Mparticles& mprts, MfieldsState& mflds) { auto vals = item(mprts, mflds); diff --git a/src/libpsc/tests/test_boundary_injector.cxx b/src/libpsc/tests/test_boundary_injector.cxx index 37a02759e..d91e31325 100644 --- a/src/libpsc/tests/test_boundary_injector.cxx +++ b/src/libpsc/tests/test_boundary_injector.cxx @@ -138,7 +138,7 @@ TEST(BoundaryInjectorTest, Integration1Particle) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; + DiagEnergies oute{grid.comm(), 0}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); auto psc = @@ -202,7 +202,7 @@ TEST(BoundaryInjectorTest, IntegrationManyParticles) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; + DiagEnergies oute{grid.comm(), 0}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); auto psc = @@ -266,7 +266,7 @@ TEST(BoundaryInjectorTest, IntegrationManySpecies) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; + DiagEnergies oute{grid.comm(), 0}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); auto inject_electrons = diff --git a/src/libpsc/tests/test_open_bcs_integration.cxx b/src/libpsc/tests/test_open_bcs_integration.cxx index 71feedceb..b78d14a78 100644 --- a/src/libpsc/tests/test_open_bcs_integration.cxx +++ b/src/libpsc/tests/test_open_bcs_integration.cxx @@ -109,7 +109,7 @@ TEST(OpenBcsTest, IntegrationY) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; + DiagEnergies oute{grid.comm(), 0}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); auto psc = diff --git a/src/libpsc/tests/test_reflective_bcs_integration.cxx b/src/libpsc/tests/test_reflective_bcs_integration.cxx index e78984163..cbcfb860c 100644 --- a/src/libpsc/tests/test_reflective_bcs_integration.cxx +++ b/src/libpsc/tests/test_reflective_bcs_integration.cxx @@ -99,7 +99,7 @@ TEST(ReflectiveBcsTest, IntegrationY) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; + DiagEnergies oute{grid.comm(), 0}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); auto psc = @@ -187,7 +187,7 @@ TEST(ReflectiveBcsTest, IntegrationZ) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; + DiagEnergies oute{grid.comm(), 0}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); auto psc = diff --git a/src/psc_2d_shock.cxx b/src/psc_2d_shock.cxx index ca3a27ad5..9f36d6f92 100644 --- a/src/psc_2d_shock.cxx +++ b/src/psc_2d_shock.cxx @@ -480,7 +480,7 @@ void run() OutputParticles outp{grid, outp_params}; int oute_interval = -100; - DiagEnergies oute{grid.comm(), oute_interval}; + DiagEnergies oute{grid.comm(), oute_interval}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); diff --git a/src/psc_bgk.cxx b/src/psc_bgk.cxx index 0141ec7c2..a55d88efd 100644 --- a/src/psc_bgk.cxx +++ b/src/psc_bgk.cxx @@ -534,7 +534,7 @@ static void run(int argc, char** argv) OutputParticles outp{grid, outp_params}; int oute_interval = -100; - DiagEnergies oute{grid.comm(), oute_interval}; + DiagEnergies oute{grid.comm(), oute_interval}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); diff --git a/src/psc_bubble_yz.cxx b/src/psc_bubble_yz.cxx index 93c67ca7f..0ecab12ca 100644 --- a/src/psc_bubble_yz.cxx +++ b/src/psc_bubble_yz.cxx @@ -335,7 +335,7 @@ static void run() OutputParticles outp{grid, outp_params}; int oute_interval = 100; - DiagEnergies oute{grid.comm(), oute_interval}; + DiagEnergies oute{grid.comm(), oute_interval}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); diff --git a/src/psc_flatfoil_yz.cxx b/src/psc_flatfoil_yz.cxx index f2832f164..a279f2104 100644 --- a/src/psc_flatfoil_yz.cxx +++ b/src/psc_flatfoil_yz.cxx @@ -544,7 +544,7 @@ void run() OutputParticles outp{grid, outp_params}; int oute_interval = -100; - DiagEnergies oute{grid.comm(), oute_interval}; + DiagEnergies oute{grid.comm(), oute_interval}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); diff --git a/src/psc_harris_yz.cxx b/src/psc_harris_yz.cxx index aa2df93a2..8846bc80c 100644 --- a/src/psc_harris_yz.cxx +++ b/src/psc_harris_yz.cxx @@ -420,7 +420,7 @@ void run() OutputParticles outp{grid, outp_params}; int oute_interval = -100; - DiagEnergies oute{grid.comm(), oute_interval}; + DiagEnergies oute{grid.comm(), oute_interval}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); diff --git a/src/psc_radiation.cxx b/src/psc_radiation.cxx index 898fb7d1f..d1c8b9c4a 100644 --- a/src/psc_radiation.cxx +++ b/src/psc_radiation.cxx @@ -290,7 +290,7 @@ void run() OutputParticles outp{grid, outp_params}; int oute_interval = -100; - DiagEnergies oute{grid.comm(), oute_interval}; + DiagEnergies oute{grid.comm(), oute_interval}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); diff --git a/src/psc_shock.cxx b/src/psc_shock.cxx index f89761745..d718206dc 100644 --- a/src/psc_shock.cxx +++ b/src/psc_shock.cxx @@ -302,7 +302,7 @@ static void run(int argc, char** argv) OutputParticles outp{grid, outp_params}; int oute_interval = -100; - DiagEnergies oute{grid.comm(), oute_interval}; + DiagEnergies oute{grid.comm(), oute_interval}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); diff --git a/src/psc_whistler.cxx b/src/psc_whistler.cxx index 6437bdac1..778138f76 100644 --- a/src/psc_whistler.cxx +++ b/src/psc_whistler.cxx @@ -314,7 +314,7 @@ void run() OutputParticles outp{grid, outp_params}; int oute_interval = 100; - DiagEnergies oute{grid.comm(), oute_interval}; + DiagEnergies oute{grid.comm(), oute_interval}; auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); From 95256dec37693030ee5b5325a32a94e09672fc86 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 27 Jan 2026 07:52:17 -0500 Subject: [PATCH 18/22] psc; *: abstract diagnostics --- src/include/psc.hxx | 55 +++++++++++++------ src/libpsc/tests/test_boundary_injector.cxx | 30 ++++++---- .../tests/test_open_bcs_integration.cxx | 10 ++-- .../tests/test_reflective_bcs_integration.cxx | 20 ++++--- src/psc_2d_shock.cxx | 10 ++-- src/psc_bgk.cxx | 11 ++-- src/psc_bubble_yz.cxx | 11 ++-- src/psc_flatfoil_yz.cxx | 11 ++-- src/psc_harris_yz.cxx | 11 ++-- src/psc_radiation.cxx | 11 ++-- src/psc_shock.cxx | 11 ++-- src/psc_whistler.cxx | 11 ++-- 12 files changed, 122 insertions(+), 80 deletions(-) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index e3f2854fd..cd0cce063 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -8,6 +8,7 @@ #include #include "../libpsc/vpic/fields_item_vpic.hxx" +#include "diagnostic_base.hxx" #include "injector_base.hxx" #include "external_current_base.hxx" #include @@ -101,7 +102,7 @@ inline double courant_length(const Grid_t::Domain& domain) // ====================================================================== // Psc -template +template struct Psc { using Mparticles = typename PscConfig::Mparticles; @@ -117,6 +118,8 @@ struct Psc using BndFields = typename PscConfig::BndFields; using BndParticles = typename PscConfig::BndParticles; using Dim = typename PscConfig::Dim; + using DiagnosticBaseT = DiagnosticBase; + using ParticleDiagnosticBaseT = ParticleDiagnosticBase; using InjectorBaseT = InjectorBase; using ExternalCurrentBaseT = ExternalCurrentBase; @@ -125,7 +128,7 @@ struct Psc Psc(const PscParams& params, Grid_t& grid, MfieldsState& mflds, Mparticles& mprts, Balance& balance, Collision& collision, Checks& checks, - Marder& marder, Diagnostics& diagnostics) + Marder& marder) : p_{params}, grid_{&grid}, mflds_{mflds}, @@ -135,7 +138,6 @@ struct Psc checks_{checks}, marder_{marder}, bndp_{grid}, - diagnostics_{diagnostics}, checkpointing_{params.write_checkpoint_every_step} { time_start_ = MPI_Wtime(); @@ -175,6 +177,23 @@ struct Psc } } + void add_diagnostic(DiagnosticBaseT* diagnostic) + { + if (diagnostic) { + diagnostics_.push_back(diagnostic); + } + } + + void add_diagnostic(ParticleDiagnosticBaseT* diagnostic) + { + if (diagnostic) { + diagnostics_.push_back(new DiagnosticFromLambda( + [&](Mparticles& mprts, MfieldsState& mflds) { + return diagnostic->perform_diagnostic(mprts); + })); + } + } + // ---------------------------------------------------------------------- // initialize_stats @@ -230,7 +249,7 @@ struct Psc // initial output / stats mpi_printf(grid().comm(), "Performing initial diagnostics.\n"); - diagnostics(); + perform_diagnostics(); psc_stats_val[st_nr_particles] = mprts_.size(); @@ -258,7 +277,7 @@ struct Psc step(); - diagnostics(); + perform_diagnostics(); psc_stats_stop(st_time_step); prof_stop(pr); @@ -476,9 +495,14 @@ private: } // ---------------------------------------------------------------------- - // diagnostics + // perform_diagnostics - void diagnostics() { diagnostics_(mprts_, mflds_); } + void perform_diagnostics() + { + for (auto diagnostic : diagnostics_) { + diagnostic->perform_diagnostic(mprts_, mflds_); + } + } // ---------------------------------------------------------------------- // print_status @@ -506,7 +530,7 @@ protected: Collision& collision_; Checks& checks_; Marder& marder_; - Diagnostics& diagnostics_; + std::vector diagnostics_; std::vector injectors_; std::vector external_currents_; @@ -534,14 +558,13 @@ protected: template -Psc makePscIntegrator( - const PscParams& params, Grid_t& grid, MfieldsState& mflds, Mparticles& mprts, - Balance& balance, Collision& collision, Checks& checks, Marder& marder, - Diagnostics& diagnostics) + typename Marder> +Psc makePscIntegrator(const PscParams& params, Grid_t& grid, + MfieldsState& mflds, Mparticles& mprts, + Balance& balance, Collision& collision, + Checks& checks, Marder& marder) { - return {params, grid, mflds, mprts, balance, - collision, checks, marder, diagnostics}; + return {params, grid, mflds, mprts, balance, collision, checks, marder}; } // ====================================================================== @@ -637,4 +660,4 @@ void vpic_create_diagnostics(int interval) {} // ---------------------------------------------------------------------- // vpic_setup_diagnostics -void vpic_setup_diagnostics() {} +void vpic_setup_perform_diagnostics() {} diff --git a/src/libpsc/tests/test_boundary_injector.cxx b/src/libpsc/tests/test_boundary_injector.cxx index d91e31325..b57f0b1fd 100644 --- a/src/libpsc/tests/test_boundary_injector.cxx +++ b/src/libpsc/tests/test_boundary_injector.cxx @@ -139,11 +139,13 @@ TEST(BoundaryInjectorTest, Integration1Particle) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; DiagEnergies oute{grid.comm(), 0}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - auto psc = - makePscIntegrator(psc_params, grid, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, grid, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); psc.add_injector( new BoundaryInjector( @@ -203,11 +205,13 @@ TEST(BoundaryInjectorTest, IntegrationManyParticles) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; DiagEnergies oute{grid.comm(), 0}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - auto psc = - makePscIntegrator(psc_params, grid, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, grid, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); psc.add_injector( new BoundaryInjector( @@ -267,7 +271,6 @@ TEST(BoundaryInjectorTest, IntegrationManySpecies) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; DiagEnergies oute{grid.comm(), 0}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); auto inject_electrons = BoundaryInjector{ @@ -276,9 +279,12 @@ TEST(BoundaryInjectorTest, IntegrationManySpecies) BoundaryInjector{ ParticleGenerator(-1, 1), grid}; - auto psc = - makePscIntegrator(psc_params, grid, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, grid, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); psc.add_injector(&inject_ions); psc.add_injector(&inject_electrons); diff --git a/src/libpsc/tests/test_open_bcs_integration.cxx b/src/libpsc/tests/test_open_bcs_integration.cxx index b78d14a78..58bf3b864 100644 --- a/src/libpsc/tests/test_open_bcs_integration.cxx +++ b/src/libpsc/tests/test_open_bcs_integration.cxx @@ -110,11 +110,13 @@ TEST(OpenBcsTest, IntegrationY) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; DiagEnergies oute{grid.comm(), 0}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); // ---------------------------------------------------------------------- // set up initial conditions diff --git a/src/libpsc/tests/test_reflective_bcs_integration.cxx b/src/libpsc/tests/test_reflective_bcs_integration.cxx index cbcfb860c..5ce8040f0 100644 --- a/src/libpsc/tests/test_reflective_bcs_integration.cxx +++ b/src/libpsc/tests/test_reflective_bcs_integration.cxx @@ -100,11 +100,13 @@ TEST(ReflectiveBcsTest, IntegrationY) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; DiagEnergies oute{grid.comm(), 0}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); // ---------------------------------------------------------------------- // set up initial conditions @@ -188,11 +190,13 @@ TEST(ReflectiveBcsTest, IntegrationZ) OutputFields outf{grid, {}}; OutputParticles outp{grid, {}}; DiagEnergies oute{grid.comm(), 0}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); // ---------------------------------------------------------------------- // set up initial conditions diff --git a/src/psc_2d_shock.cxx b/src/psc_2d_shock.cxx index 9f36d6f92..a9a6bb782 100644 --- a/src/psc_2d_shock.cxx +++ b/src/psc_2d_shock.cxx @@ -482,8 +482,6 @@ void run() int oute_interval = -100; DiagEnergies oute{grid.comm(), oute_interval}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - // ---------------------------------------------------------------------- // Set up objects specific to the flatfoil case @@ -608,10 +606,12 @@ void run() // ---------------------------------------------------------------------- // hand off to PscIntegrator to run the simulation - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); psc.add_injector( new InjectFromLambda(lf_inject_heat)); diff --git a/src/psc_bgk.cxx b/src/psc_bgk.cxx index a55d88efd..c2c67fe8f 100644 --- a/src/psc_bgk.cxx +++ b/src/psc_bgk.cxx @@ -536,8 +536,6 @@ static void run(int argc, char** argv) int oute_interval = -100; DiagEnergies oute{grid.comm(), oute_interval}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - // ---------------------------------------------------------------------- // Set up initial conditions @@ -556,9 +554,12 @@ static void run(int argc, char** argv) // ---------------------------------------------------------------------- // Hand off to PscIntegrator to run the simulation - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); psc.integrate(); } diff --git a/src/psc_bubble_yz.cxx b/src/psc_bubble_yz.cxx index 0ecab12ca..ec294b0b6 100644 --- a/src/psc_bubble_yz.cxx +++ b/src/psc_bubble_yz.cxx @@ -337,8 +337,6 @@ static void run() int oute_interval = 100; DiagEnergies oute{grid.comm(), oute_interval}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - // ---------------------------------------------------------------------- // setup initial conditions @@ -352,9 +350,12 @@ static void run() // ---------------------------------------------------------------------- // hand off to PscIntegrator to run the simulation - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); psc.integrate(); } diff --git a/src/psc_flatfoil_yz.cxx b/src/psc_flatfoil_yz.cxx index a279f2104..3d0682f88 100644 --- a/src/psc_flatfoil_yz.cxx +++ b/src/psc_flatfoil_yz.cxx @@ -546,8 +546,6 @@ void run() int oute_interval = -100; DiagEnergies oute{grid.comm(), oute_interval}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - // ---------------------------------------------------------------------- // Set up objects specific to the flatfoil case @@ -680,9 +678,12 @@ void run() // ---------------------------------------------------------------------- // hand off to PscIntegrator to run the simulation - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); psc.add_injector( new InjectFromLambda(lf_inject_heat)); diff --git a/src/psc_harris_yz.cxx b/src/psc_harris_yz.cxx index 8846bc80c..3c28df80c 100644 --- a/src/psc_harris_yz.cxx +++ b/src/psc_harris_yz.cxx @@ -422,8 +422,6 @@ void run() int oute_interval = -100; DiagEnergies oute{grid.comm(), oute_interval}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - // ---------------------------------------------------------------------- // Set up objects specific to the Harris case @@ -442,9 +440,12 @@ void run() // ---------------------------------------------------------------------- // hand off to PscIntegrator to run the simulation - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); MEM_STATS(); psc.integrate(); diff --git a/src/psc_radiation.cxx b/src/psc_radiation.cxx index d1c8b9c4a..76b1f7d51 100644 --- a/src/psc_radiation.cxx +++ b/src/psc_radiation.cxx @@ -292,8 +292,6 @@ void run() int oute_interval = -100; DiagEnergies oute{grid.comm(), oute_interval}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - // ---------------------------------------------------------------------- // setup initial conditions @@ -305,9 +303,12 @@ void run() // ---------------------------------------------------------------------- // hand off to PscIntegrator to run the simulation - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); psc.add_external_current( new ExternalCurrentFromLambda(lf_ext_current)); diff --git a/src/psc_shock.cxx b/src/psc_shock.cxx index d718206dc..1ba0854fa 100644 --- a/src/psc_shock.cxx +++ b/src/psc_shock.cxx @@ -304,8 +304,6 @@ static void run(int argc, char** argv) int oute_interval = -100; DiagEnergies oute{grid.comm(), oute_interval}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - // ---------------------------------------------------------------------- // set up initial conditions @@ -315,9 +313,12 @@ static void run(int argc, char** argv) // ---------------------------------------------------------------------- // run the simulation - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); psc.integrate(); } diff --git a/src/psc_whistler.cxx b/src/psc_whistler.cxx index 778138f76..7534cc5f4 100644 --- a/src/psc_whistler.cxx +++ b/src/psc_whistler.cxx @@ -316,8 +316,6 @@ void run() int oute_interval = 100; DiagEnergies oute{grid.comm(), oute_interval}; - auto diagnostics = makeDiagnosticsDefault(outf, outp, oute); - // ---------------------------------------------------------------------- // setup initial conditions @@ -331,9 +329,12 @@ void run() // ---------------------------------------------------------------------- // hand off to PscIntegrator to run the simulation - auto psc = - makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, - collision, checks, marder, diagnostics); + auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, + balance, collision, checks, marder); + + psc.add_diagnostic(&outf); + psc.add_diagnostic(&outp); + psc.add_diagnostic(&oute); psc.integrate(); } From 77fa1a5f69a2d80f6594a7d36b72c5896ec57c30 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 27 Jan 2026 07:58:02 -0500 Subject: [PATCH 19/22] psc: update stat in perform_diagnostics --- src/include/psc.hxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index cd0cce063..a8118e0a4 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -499,9 +499,11 @@ private: void perform_diagnostics() { + psc_stats_start(st_time_output); for (auto diagnostic : diagnostics_) { diagnostic->perform_diagnostic(mprts_, mflds_); } + psc_stats_stop(st_time_output); } // ---------------------------------------------------------------------- From 119a73455fe977ee8de56cabddf4d889c7250c3d Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 27 Jan 2026 08:00:50 -0500 Subject: [PATCH 20/22] -DiagnosticsDefault; * --- src/include/DiagnosticsDefault.h | 49 ------------------- src/libpsc/tests/test_boundary_injector.cxx | 1 - .../tests/test_open_bcs_integration.cxx | 1 - src/libpsc/tests/test_reflective_bcs.cxx | 1 - .../tests/test_reflective_bcs_integration.cxx | 1 - src/psc_2d_shock.cxx | 1 - src/psc_bgk.cxx | 1 - src/psc_bubble_yz.cxx | 1 - src/psc_flatfoil_yz.cxx | 1 - src/psc_harris_yz.cxx | 1 - src/psc_radiation.cxx | 1 - src/psc_shock.cxx | 1 - src/psc_whistler.cxx | 1 - 13 files changed, 61 deletions(-) delete mode 100644 src/include/DiagnosticsDefault.h diff --git a/src/include/DiagnosticsDefault.h b/src/include/DiagnosticsDefault.h deleted file mode 100644 index b5071d01e..000000000 --- a/src/include/DiagnosticsDefault.h +++ /dev/null @@ -1,49 +0,0 @@ - -#pragma once - -#include "DiagEnergies.h" - -// ====================================================================== -// DiagnosticsDefault - -template -class DiagnosticsDefault -{ -public: - DiagnosticsDefault(OutputFields& outf, OutputParticles& outp, - OutputEnergies& oute) - : outf_{outf}, outp_{outp}, oute_{oute} - {} - - template - void operator()(Mparticles& mprts, MfieldsState& mflds) - { - psc_stats_start(st_time_output); -#ifdef VPIC -#if 0 - TIC user_diagnostics(); TOC(user_diagnostics, 1); -#endif -#else - // FIXME - outf_(mflds, mprts); -#endif - outp_(mprts); - oute_(mprts, mflds); - psc_stats_stop(st_time_output); - } - -private: - OutputFields& outf_; - OutputParticles& outp_; - OutputEnergies& oute_; -}; - -template -DiagnosticsDefault -makeDiagnosticsDefault(OutputFields& outf, OutputParticles& outp, - OutputEnergies& oute) -{ - return {outf, outp, oute}; -} diff --git a/src/libpsc/tests/test_boundary_injector.cxx b/src/libpsc/tests/test_boundary_injector.cxx index b57f0b1fd..eb138ba28 100644 --- a/src/libpsc/tests/test_boundary_injector.cxx +++ b/src/libpsc/tests/test_boundary_injector.cxx @@ -5,7 +5,6 @@ #include "boundary_injector.hxx" #include "psc.hxx" -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "../psc_config.hxx" diff --git a/src/libpsc/tests/test_open_bcs_integration.cxx b/src/libpsc/tests/test_open_bcs_integration.cxx index 58bf3b864..94955fc23 100644 --- a/src/libpsc/tests/test_open_bcs_integration.cxx +++ b/src/libpsc/tests/test_open_bcs_integration.cxx @@ -4,7 +4,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "add_ghosts_reflecting.hxx" #include "../psc_config.hxx" diff --git a/src/libpsc/tests/test_reflective_bcs.cxx b/src/libpsc/tests/test_reflective_bcs.cxx index e16721eb1..0da074977 100644 --- a/src/libpsc/tests/test_reflective_bcs.cxx +++ b/src/libpsc/tests/test_reflective_bcs.cxx @@ -4,7 +4,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "add_ghosts_reflecting.hxx" #include "../psc_config.hxx" diff --git a/src/libpsc/tests/test_reflective_bcs_integration.cxx b/src/libpsc/tests/test_reflective_bcs_integration.cxx index 5ce8040f0..d33b2eb47 100644 --- a/src/libpsc/tests/test_reflective_bcs_integration.cxx +++ b/src/libpsc/tests/test_reflective_bcs_integration.cxx @@ -4,7 +4,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "add_ghosts_reflecting.hxx" #include "../psc_config.hxx" diff --git a/src/psc_2d_shock.cxx b/src/psc_2d_shock.cxx index a9a6bb782..8a66e258a 100644 --- a/src/psc_2d_shock.cxx +++ b/src/psc_2d_shock.cxx @@ -3,7 +3,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "psc_config.hxx" diff --git a/src/psc_bgk.cxx b/src/psc_bgk.cxx index c2c67fe8f..4b39ce6b7 100644 --- a/src/psc_bgk.cxx +++ b/src/psc_bgk.cxx @@ -3,7 +3,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "psc_config.hxx" #include "input_params.hxx" diff --git a/src/psc_bubble_yz.cxx b/src/psc_bubble_yz.cxx index ec294b0b6..720789aef 100644 --- a/src/psc_bubble_yz.cxx +++ b/src/psc_bubble_yz.cxx @@ -3,7 +3,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "psc_config.hxx" diff --git a/src/psc_flatfoil_yz.cxx b/src/psc_flatfoil_yz.cxx index 3d0682f88..34eb008d4 100644 --- a/src/psc_flatfoil_yz.cxx +++ b/src/psc_flatfoil_yz.cxx @@ -3,7 +3,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "psc_config.hxx" diff --git a/src/psc_harris_yz.cxx b/src/psc_harris_yz.cxx index 3c28df80c..76ddd408d 100644 --- a/src/psc_harris_yz.cxx +++ b/src/psc_harris_yz.cxx @@ -4,7 +4,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "psc_config.hxx" diff --git a/src/psc_radiation.cxx b/src/psc_radiation.cxx index 76b1f7d51..c717a7b8e 100644 --- a/src/psc_radiation.cxx +++ b/src/psc_radiation.cxx @@ -3,7 +3,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "psc_config.hxx" diff --git a/src/psc_shock.cxx b/src/psc_shock.cxx index 1ba0854fa..8017ed604 100644 --- a/src/psc_shock.cxx +++ b/src/psc_shock.cxx @@ -2,7 +2,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "psc_config.hxx" #include "input_params.hxx" diff --git a/src/psc_whistler.cxx b/src/psc_whistler.cxx index 7534cc5f4..ae5487973 100644 --- a/src/psc_whistler.cxx +++ b/src/psc_whistler.cxx @@ -3,7 +3,6 @@ #include #include -#include "DiagnosticsDefault.h" #include "OutputFieldsDefault.h" #include "psc_config.hxx" From 17fe7abecbdd93c35467c8c37598bce0c22596eb Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 27 Jan 2026 08:03:38 -0500 Subject: [PATCH 21/22] tests: don't make diagnostics --- src/libpsc/tests/test_boundary_injector.cxx | 24 ------------------- .../tests/test_open_bcs_integration.cxx | 8 ------- .../tests/test_reflective_bcs_integration.cxx | 16 ------------- 3 files changed, 48 deletions(-) diff --git a/src/libpsc/tests/test_boundary_injector.cxx b/src/libpsc/tests/test_boundary_injector.cxx index eb138ba28..2d8b1e93f 100644 --- a/src/libpsc/tests/test_boundary_injector.cxx +++ b/src/libpsc/tests/test_boundary_injector.cxx @@ -135,17 +135,9 @@ TEST(BoundaryInjectorTest, Integration1Particle) Collision collision{grid, 0, 0.1}; Marder marder(grid, 0.9, 3, false); - OutputFields outf{grid, {}}; - OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; - auto psc = makePscIntegrator(psc_params, grid, mflds, mprts, balance, collision, checks, marder); - psc.add_diagnostic(&outf); - psc.add_diagnostic(&outp); - psc.add_diagnostic(&oute); - psc.add_injector( new BoundaryInjector( ParticleGenerator(1, 1), grid)); @@ -201,17 +193,9 @@ TEST(BoundaryInjectorTest, IntegrationManyParticles) Collision collision{grid, 0, 0.1}; Marder marder(grid, 0.9, 3, false); - OutputFields outf{grid, {}}; - OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; - auto psc = makePscIntegrator(psc_params, grid, mflds, mprts, balance, collision, checks, marder); - psc.add_diagnostic(&outf); - psc.add_diagnostic(&outp); - psc.add_diagnostic(&oute); - psc.add_injector( new BoundaryInjector( ParticleGenerator(-1, 1), grid)); @@ -267,10 +251,6 @@ TEST(BoundaryInjectorTest, IntegrationManySpecies) Collision collision{grid, 0, 0.1}; Marder marder(grid, 0.9, 3, false); - OutputFields outf{grid, {}}; - OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; - auto inject_electrons = BoundaryInjector{ ParticleGenerator(-1, 0), grid}; @@ -281,10 +261,6 @@ TEST(BoundaryInjectorTest, IntegrationManySpecies) auto psc = makePscIntegrator(psc_params, grid, mflds, mprts, balance, collision, checks, marder); - psc.add_diagnostic(&outf); - psc.add_diagnostic(&outp); - psc.add_diagnostic(&oute); - psc.add_injector(&inject_ions); psc.add_injector(&inject_electrons); diff --git a/src/libpsc/tests/test_open_bcs_integration.cxx b/src/libpsc/tests/test_open_bcs_integration.cxx index 94955fc23..e88777562 100644 --- a/src/libpsc/tests/test_open_bcs_integration.cxx +++ b/src/libpsc/tests/test_open_bcs_integration.cxx @@ -106,17 +106,9 @@ TEST(OpenBcsTest, IntegrationY) Collision collision{grid, 0, 0.1}; Marder marder(grid, 0.9, 3, false); - OutputFields outf{grid, {}}; - OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; - auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, collision, checks, marder); - psc.add_diagnostic(&outf); - psc.add_diagnostic(&outp); - psc.add_diagnostic(&oute); - // ---------------------------------------------------------------------- // set up initial conditions diff --git a/src/libpsc/tests/test_reflective_bcs_integration.cxx b/src/libpsc/tests/test_reflective_bcs_integration.cxx index d33b2eb47..c04c5d20c 100644 --- a/src/libpsc/tests/test_reflective_bcs_integration.cxx +++ b/src/libpsc/tests/test_reflective_bcs_integration.cxx @@ -96,17 +96,9 @@ TEST(ReflectiveBcsTest, IntegrationY) Collision collision{grid, 0, 0.1}; Marder marder(grid, 0.9, 3, false); - OutputFields outf{grid, {}}; - OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; - auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, collision, checks, marder); - psc.add_diagnostic(&outf); - psc.add_diagnostic(&outp); - psc.add_diagnostic(&oute); - // ---------------------------------------------------------------------- // set up initial conditions @@ -186,17 +178,9 @@ TEST(ReflectiveBcsTest, IntegrationZ) Collision collision{grid, 0, 0.1}; Marder marder(grid, 0.9, 3, false); - OutputFields outf{grid, {}}; - OutputParticles outp{grid, {}}; - DiagEnergies oute{grid.comm(), 0}; - auto psc = makePscIntegrator(psc_params, *grid_ptr, mflds, mprts, balance, collision, checks, marder); - psc.add_diagnostic(&outf); - psc.add_diagnostic(&outp); - psc.add_diagnostic(&oute); - // ---------------------------------------------------------------------- // set up initial conditions From 70c54da19d0a29819ffcaa550a5466fea9eacabb Mon Sep 17 00:00:00 2001 From: James McClung Date: Thu, 5 Feb 2026 16:16:41 -0500 Subject: [PATCH 22/22] psc: fix capture by ref -> segfault --- src/include/psc.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index a8118e0a4..e275ae7fe 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -188,7 +188,7 @@ struct Psc { if (diagnostic) { diagnostics_.push_back(new DiagnosticFromLambda( - [&](Mparticles& mprts, MfieldsState& mflds) { + [=](Mparticles& mprts, MfieldsState& mflds) { return diagnostic->perform_diagnostic(mprts); })); }