From 3ff90c958216e5b71b7f56f3843e9feb05393252 Mon Sep 17 00:00:00 2001 From: Marco Garten Date: Tue, 17 Sep 2024 14:22:08 -0700 Subject: [PATCH] Continue averaging period logic - Implement warnings and errors for certain inputs concerning averaging periods --- Source/Diagnostics/FullDiagnostics.H | 2 +- Source/Diagnostics/FullDiagnostics.cpp | 53 ++++++++++++++++++++----- Source/Diagnostics/MultiDiagnostics.H | 2 - Source/Diagnostics/MultiDiagnostics.cpp | 8 ++-- Source/Diagnostics/WarpXOpenPMD.cpp | 2 + 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/Source/Diagnostics/FullDiagnostics.H b/Source/Diagnostics/FullDiagnostics.H index bd54f9475be..7625216ae1b 100644 --- a/Source/Diagnostics/FullDiagnostics.H +++ b/Source/Diagnostics/FullDiagnostics.H @@ -19,7 +19,7 @@ public: * Dynamic corresponds to a moving period for averaging where the start step * is as many steps before the output interval as the averaging period is long. */ - enum TimeAverageType {None, Static, Dynamic}; + enum struct TimeAverageType {None, Static, Dynamic}; private: /** Read user-requested parameters for full diagnostics */ void ReadParameters (); diff --git a/Source/Diagnostics/FullDiagnostics.cpp b/Source/Diagnostics/FullDiagnostics.cpp index 1fcbf636486..edac52edde1 100644 --- a/Source/Diagnostics/FullDiagnostics.cpp +++ b/Source/Diagnostics/FullDiagnostics.cpp @@ -118,17 +118,32 @@ FullDiagnostics::ReadParameters () ); } + const bool averaging_period_steps_specified = pp_diag_name.query( + "average_period_steps", m_average_period_steps + ); + const bool averaging_period_time_specified = pp_diag_name.queryWithParser( + "average_period_time", m_average_period_time + ); + if (m_time_average_type == TimeAverageType::Static) { + // This fails if users do not specify a start. pp_diag_name.get("average_start_step", m_average_start_step); + + if (averaging_period_time_specified || averaging_period_steps_specified) { + const std::string period_spec_warn_msg = "An averaging period was specified for the 'static_start' averaging mode" \ + "but will be IGNORED. Averaging will be performed between step" \ + + std::to_string(m_average_start_step) \ + + "and the specified intervals."; + ablastr::warn_manager::WMRecordWarning( + "Diagnostics", + period_spec_warn_msg, + ablastr::warn_manager::WarnPriority::medium + ); + } + } if (m_time_average_type == TimeAverageType::Dynamic) { - const bool averaging_period_steps_specified = pp_diag_name.query( - "average_period_steps", m_average_period_steps - ); - const bool averaging_period_time_specified = pp_diag_name.queryWithParser( - "average_period_time", m_average_period_time - ); // one of the two averaging period options must be set but neither none nor both if ( (averaging_period_steps_specified && averaging_period_time_specified) @@ -218,20 +233,36 @@ FullDiagnostics::DoDump (int step, int /*i_buffer*/, bool force_flush) bool FullDiagnostics::DoComputeAndPack (int step, bool force_flush) { - if (m_time_averaging == "dynamic_start") { + if (m_time_average_type == TimeAverageType::Dynamic) { m_average_start_step = m_intervals.nextContains(step) - m_average_period_steps; + // check that the periods do not overlap and that the start step is not negative + if (m_average_start_step > 0) { + if (m_average_start_step < m_intervals.previousContains(step)) { + WARPX_ABORT_WITH_MESSAGE( + "Averaging periods may not overlap within a single diagnostic. " + "Please create a second diagnostic for overlapping time averaging periods " + "and account for the increased memory consumption." + ); + } else { + WARPX_ABORT_WITH_MESSAGE("The step to begin time averaging may not be a negative number."); + } + } } - // add logic here to do compute and pack if m_intervals.contains (step+1-time_average_period) or if (cur_step>time_average_startstep) + // Start averaging at output step (from diag.intervals) - period + 1 bool in_averaging_period = false; if (step > m_intervals.nextContains(step) - m_average_start_step && step <= m_intervals.nextContains(step)) { in_averaging_period = true; + + if (m_time_average_type == TimeAverageType::Static) { + // Update time averaging period to current step + m_average_period_steps = step - m_average_start_step; + } } // Data must be computed and packed for full diagnostics // whenever the data needs to be flushed. return (force_flush || m_intervals.contains(step+1) || in_averaging_period); - //return (force_flush || m_intervals.contains(step+1) ); } @@ -666,14 +697,14 @@ FullDiagnostics::InitializeBufferData (int i_buffer, int lev, bool restart ) { if (m_time_average_type == TimeAverageType::Dynamic) { - // already checked in ReadParameters that only one of them is set + // already checked in ReadParameters that only one of the parameters is set + // calculate the other averaging period parameter from the other one, respectively if (m_average_period_steps > 0) { m_average_period_time = m_average_period_steps * warpx.getdt(0); } else if (m_average_period_time > 0) { m_average_period_steps = static_cast (std::round(m_average_period_time / warpx.getdt(0))); } - // CONTINUE HERE } } diff --git a/Source/Diagnostics/MultiDiagnostics.H b/Source/Diagnostics/MultiDiagnostics.H index 75b51527242..a22e20b44da 100644 --- a/Source/Diagnostics/MultiDiagnostics.H +++ b/Source/Diagnostics/MultiDiagnostics.H @@ -11,8 +11,6 @@ #include #include -/** All types of diagnostics. */ -enum struct DiagTypes {Full, BackTransformed, BoundaryScraping, TimeAveraged}; /** * \brief This class contains a vector of all diagnostics in the simulation. diff --git a/Source/Diagnostics/MultiDiagnostics.cpp b/Source/Diagnostics/MultiDiagnostics.cpp index 739d5ed330c..1dd4c62c0f5 100644 --- a/Source/Diagnostics/MultiDiagnostics.cpp +++ b/Source/Diagnostics/MultiDiagnostics.cpp @@ -22,13 +22,13 @@ MultiDiagnostics::MultiDiagnostics () alldiags.resize( ndiags ); for (int i=0; i(i, diags_names[i]); + alldiags[i] = std::make_unique(i, diags_names[i], diags_types[i]); } else if ( diags_types[i] == DiagTypes::TimeAveraged ){ - alldiags[i] = std::make_unique(i, diags_names[i]); + alldiags[i] = std::make_unique(i, diags_names[i], diags_types[i]); } else if ( diags_types[i] == DiagTypes::BackTransformed ){ - alldiags[i] = std::make_unique(i, diags_names[i]); + alldiags[i] = std::make_unique(i, diags_names[i], diags_types[i]); } else if ( diags_types[i] == DiagTypes::BoundaryScraping ){ - alldiags[i] = std::make_unique(i, diags_names[i]); + alldiags[i] = std::make_unique(i, diags_names[i], diags_types[i]); } else { WARPX_ABORT_WITH_MESSAGE("Unknown diagnostic type"); } diff --git a/Source/Diagnostics/WarpXOpenPMD.cpp b/Source/Diagnostics/WarpXOpenPMD.cpp index 4e1b6238adf..e38ae8c8300 100644 --- a/Source/Diagnostics/WarpXOpenPMD.cpp +++ b/Source/Diagnostics/WarpXOpenPMD.cpp @@ -1195,6 +1195,8 @@ WarpXOpenPMDPlot::SetupFields ( openPMD::Container< openPMD::Mesh >& meshes, if (WarpX::do_dive_cleaning) { meshes.setAttribute("chargeCorrectionParameters", "period=1"); } + // TODO set meta-data information for time-averaged quantities + // but we need information of the specific diagnostic in here }