From cc371a38fcad841ef1ecb4d3a1b1cf8fa88b1165 Mon Sep 17 00:00:00 2001 From: Michael Kuhn Date: Mon, 31 Mar 2025 11:50:06 -0600 Subject: [PATCH 1/8] Subvolume postprocessing tool - code compiles --- amr-wind/utilities/CMakeLists.txt | 1 + amr-wind/utilities/sampling/CMakeLists.txt | 5 +- amr-wind/utilities/subvolume/CMakeLists.txt | 5 + .../subvolume/RectangularSubvolume.H | 65 ++++++ .../subvolume/RectangularSubvolume.cpp | 111 +++++++++ amr-wind/utilities/subvolume/Subvolume.H | 96 ++++++++ amr-wind/utilities/subvolume/Subvolume.cpp | 219 ++++++++++++++++++ amr-wind/utilities/subvolume/SubvolumeBase.H | 53 +++++ 8 files changed, 553 insertions(+), 2 deletions(-) create mode 100644 amr-wind/utilities/subvolume/CMakeLists.txt create mode 100644 amr-wind/utilities/subvolume/RectangularSubvolume.H create mode 100644 amr-wind/utilities/subvolume/RectangularSubvolume.cpp create mode 100644 amr-wind/utilities/subvolume/Subvolume.H create mode 100644 amr-wind/utilities/subvolume/Subvolume.cpp create mode 100644 amr-wind/utilities/subvolume/SubvolumeBase.H diff --git a/amr-wind/utilities/CMakeLists.txt b/amr-wind/utilities/CMakeLists.txt index a91a172609..6310c6db40 100644 --- a/amr-wind/utilities/CMakeLists.txt +++ b/amr-wind/utilities/CMakeLists.txt @@ -22,6 +22,7 @@ target_sources(${amr_wind_lib_name} add_subdirectory(tagging) add_subdirectory(sampling) +add_subdirectory(subvolume) add_subdirectory(averaging) if (AMR_WIND_ENABLE_NETCDF) diff --git a/amr-wind/utilities/sampling/CMakeLists.txt b/amr-wind/utilities/sampling/CMakeLists.txt index f5de390008..de26ee9f11 100644 --- a/amr-wind/utilities/sampling/CMakeLists.txt +++ b/amr-wind/utilities/sampling/CMakeLists.txt @@ -10,10 +10,11 @@ target_sources(${amr_wind_lib_name} DTUSpinnerSampler.cpp PlaneSampler.cpp ProbeSampler.cpp + FreeSurfaceSampler.cpp + VolumeSampler.cpp + # The ones below should probably be moved FieldNorms.cpp KineticEnergy.cpp Enstrophy.cpp - FreeSurfaceSampler.cpp - VolumeSampler.cpp WaveEnergy.cpp ) diff --git a/amr-wind/utilities/subvolume/CMakeLists.txt b/amr-wind/utilities/subvolume/CMakeLists.txt new file mode 100644 index 0000000000..9fee1a83f2 --- /dev/null +++ b/amr-wind/utilities/subvolume/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${amr_wind_lib_name} + PRIVATE + + Subvolume.cpp + ) diff --git a/amr-wind/utilities/subvolume/RectangularSubvolume.H b/amr-wind/utilities/subvolume/RectangularSubvolume.H new file mode 100644 index 0000000000..8ee4db1fc0 --- /dev/null +++ b/amr-wind/utilities/subvolume/RectangularSubvolume.H @@ -0,0 +1,65 @@ +#ifndef LINESAMPLER_H +#define LINESAMPLER_H + +#include "amr-wind/utilities/subvolume/SubvolumeBase.H" + +namespace amr_wind::subvolume { + +/** Get subvolume defined by 3D rectangle + * \ingroup subvolume + * + * Defines probes along a line defined by `start` and `end` coordinates and + * divides it into equal segments as determined by `num_points`. The length of + * each segment is given by \f[ (end - start) / (num_points - 1) \f] + */ +class RectangularSubvolume + : public SubvolumeBase::Register +{ +public: + static std::string identifier() { return "Rectangular"; } + + explicit RectangularSubvolume(const CFDSim& /*sim*/); + + ~RectangularSubvolume() override; + + /** Read user inputs and initialize the subvolume object + * + * \param key Prefix used to parse inputs from file + */ + void initialize(const std::string& key) override; + + //! Check if inputs have a valid correspondence in the mesh and save + //! quantities for output steps + void evaluate_inputs() override; + + void post_regrid_actions() override { evaluate_inputs(); } + + //! Name of this subvolume object + std::string label() const override { return m_label; } + std::string& label() override { return m_label; } + + //! Type of this subvolume object + std::string subvolumetype() const override { return identifier(); } + + int lev() const override { return m_lev_for_sub; } + + amrex::BoxArray box_array() const override { return m_ba; } + +protected: + const CFDSim& m_sim; + + amrex::Vector m_origin; + amrex::Vector m_npts_vec; + amrex::Vector m_dx_vec; + amrex::Vector m_chunk_size_vec; + + int m_lev_for_sub{0}; + + amrex::BoxArray m_ba; + + std::string m_label; +}; + +} // namespace amr_wind::subvolume + +#endif /* LINESAMPLER_H */ diff --git a/amr-wind/utilities/subvolume/RectangularSubvolume.cpp b/amr-wind/utilities/subvolume/RectangularSubvolume.cpp new file mode 100644 index 0000000000..39a46253c3 --- /dev/null +++ b/amr-wind/utilities/subvolume/RectangularSubvolume.cpp @@ -0,0 +1,111 @@ +#include "amr-wind/utilities/subvolume/RectangularSubvolume.H" +#include "amr-wind/utilities/constants.H" +#include "amr-wind/CFDSim.H" + +#include "AMReX_ParmParse.H" + +namespace amr_wind::subvolume { + +RectangularSubvolume::RectangularSubvolume(const CFDSim& sim) : m_sim(sim) {} + +RectangularSubvolume::~RectangularSubvolume() = default; + +void RectangularSubvolume::initialize(const std::string& key) +{ + amrex::ParmParse pp(key); + + pp.getarr("origin", m_origin); + pp.getarr("num_points", m_npts_vec); + pp.getarr("dx_vec", m_dx_vec); + + m_chunk_size_vec.resize(AMREX_SPACEDIM); + m_chunk_size_vec[0] = m_sim.mesh().maxGridSize(0)[0]; + m_chunk_size_vec[1] = m_sim.mesh().maxGridSize(0)[1]; + m_chunk_size_vec[2] = m_sim.mesh().maxGridSize(0)[2]; + pp.queryarr("chunk_size", m_chunk_size_vec); +} + +void RectangularSubvolume::evaluate_inputs() +{ + + int lev_for_sub = 0; + + bool found = false; + const auto& geom = m_sim.mesh().Geom(); + for (int i = 0; i < m_sim.repo().num_active_levels(); i++) { + if (!found) { + if (std::abs(m_dx_vec[0] - geom[i].CellSize(0)) < + constants::LOOSE_TOL && + std::abs(m_dx_vec[1] - geom[i].CellSize(1)) < + constants::LOOSE_TOL && + std::abs(m_dx_vec[2] - geom[i].CellSize(2)) < + constants::LOOSE_TOL) { + + /* amrex::Print() << "Resolution specified matches that of level + " + << i << std::endl; */ + found = true; + m_lev_for_sub = i; + } + } + } + + if (!found) { + amrex::Abort( + "Resolution specified for subvolume does not match the resolution " + "of any of the mesh levels."); + } + + // ************************************************************** + // Now that we know which level we're at, we can figure out which (i,j,k) + // the origin corresponds to Note we use 1.0001 as a fudge factor since the + // division of two reals --> integer will do a floor + // ************************************************************** + int i0 = static_cast( + (m_origin[0] - geom[m_lev_for_sub].ProbLo(0)) * 1.0001 / m_dx_vec[0]); + int j0 = static_cast( + (m_origin[1] - geom[m_lev_for_sub].ProbLo(1)) * 1.0001 / m_dx_vec[1]); + int k0 = static_cast( + (m_origin[2] - geom[m_lev_for_sub].ProbLo(2)) * 1.0001 / m_dx_vec[2]); + + found = false; + if (std::abs(geom[lev_for_sub].ProbLo(0) + i0 * m_dx_vec[0] - m_origin[0]) < + constants::LOOSE_TOL && + std::abs(geom[lev_for_sub].ProbLo(1) + i0 * m_dx_vec[1] - m_origin[1]) < + constants::LOOSE_TOL && + std::abs(geom[lev_for_sub].ProbLo(2) + i0 * m_dx_vec[2] - m_origin[2]) < + constants::LOOSE_TOL) { + amrex::Print() << "Specified origin is the lower left corner of cell " + << amrex::IntVect(i0, j0, k0) << std::endl; + found = true; + } + + if (!found) { + amrex::Abort( + "Origin specified does not correspond to a node at this level."); + } + + amrex::Box domain(geom[m_lev_for_sub].Domain()); + + amrex::Box bx( + amrex::IntVect(i0, j0, k0), + amrex::IntVect( + i0 + m_npts_vec[0] - 1, j0 + m_npts_vec[1] - 1, + k0 + m_npts_vec[2] - 1)); + amrex::Print() << "Box requested is " << bx << std::endl; + + if (!domain.contains(bx)) { + amrex::Abort("Box requested is larger than the existing domain"); + } + + amrex::IntVect chunk_size(m_chunk_size_vec[0], m_chunk_size_vec[1], m_chunk_size_vec[2]); + + amrex::BoxArray ba(bx); + ba.maxSize(chunk_size); + + amrex::Print() << "BoxArray is " << ba << std::endl; + + m_ba = ba; +} + +} // namespace amr_wind::subvolume diff --git a/amr-wind/utilities/subvolume/Subvolume.H b/amr-wind/utilities/subvolume/Subvolume.H new file mode 100644 index 0000000000..4e05adf7e5 --- /dev/null +++ b/amr-wind/utilities/subvolume/Subvolume.H @@ -0,0 +1,96 @@ +#ifndef SUBVOLUME_H +#define SUBVOLUME_H + +#include + +#include "amr-wind/CFDSim.H" +#include "amr-wind/utilities/DerivedQuantity.H" +#include "amr-wind/utilities/PostProcessing.H" +#include "amr-wind/utilities/subvolume/SubvolumeBase.H" +#include + +/** + * \defgroup subvolume Mesh data subvolume utilities + * Mesh data subvolume utilities + * + * Subvolume is a data-retrieval tool designed to obtain partitions (chunks) + * directly from the AMR-Wind computational mesh. It is distinct from the + * sampling utilities because it does not use particles and is therefore + * confined to the actual cell locations; however, it is another way to sample + * data from the simulation. In essence, subvolume outputs are like plotfiles + * but only contain a portion of the domain. + * + * \ingroup utilities + */ + +namespace amr_wind::subvolume { + +class Subvolume : public PostProcessBase::Register +{ +public: + static std::string identifier() { return "Subvolume"; } + + Subvolume(CFDSim& /*sim*/, std::string /*label*/); + + ~Subvolume() override; + + //! Perform actions before mesh is created + void pre_init_actions() override {} + + //! Read user inputs for chunks, output timing + void initialize() override; + + //! Do any work that needs to happen after regrid + void post_regrid_actions() override; + + //! Get chunks and output to disk + void post_advance_work() override; + + void write_subvolume(); + + const amrex::Vector& var_names() const { return m_var_names; } + +protected: +private: + CFDSim& m_sim; + + amrex::Vector> m_subvolumes; + + //! List of variable names for output + amrex::Vector m_var_names; + + //! List of fields to be sampled for this collection of probes + amrex::Vector m_fields; + + //! List of IntFields to be sampled for this collection of probes + amrex::Vector m_int_fields; + + //! List of derived fields to be sampled for this collection of probes + std::unique_ptr m_derived_mgr; + + /** Name of this subvolume object. + * + * The label is used to read user inputs from file and is also used for + * naming files directories. + */ + const std::string m_label; + + // number of field components + int m_ncomp{0}; + + // number of int field components + int m_nicomp{0}; + + // number of derived field components + int m_ndcomp{0}; + + //! Frequency of data output + int m_out_freq{100}; + + //! Delay number of timestep before output + int m_out_delay{0}; +}; + +} // namespace amr_wind::subvolume + +#endif /* SUBVOLUME_H */ diff --git a/amr-wind/utilities/subvolume/Subvolume.cpp b/amr-wind/utilities/subvolume/Subvolume.cpp new file mode 100644 index 0000000000..05681e919b --- /dev/null +++ b/amr-wind/utilities/subvolume/Subvolume.cpp @@ -0,0 +1,219 @@ +#include +#include + +#include "amr-wind/utilities/subvolume/Subvolume.H" +#include "amr-wind/utilities/io_utils.H" +#include "amr-wind/utilities/IOManager.H" +#include "AMReX_MultiFabUtil.H" + +#include "AMReX_ParmParse.H" + +namespace amr_wind::subvolume { + +Subvolume::Subvolume(CFDSim& sim, std::string label) + : m_sim(sim) + , m_derived_mgr(new DerivedQtyMgr(m_sim.repo())) + , m_label(std::move(label)) +{} + +Subvolume::~Subvolume() = default; + +void Subvolume::initialize() +{ + BL_PROFILE("amr-wind::Subvolume::initialize"); + + // Labels for the different sampler types + amrex::Vector labels; + // Fields to be sampled - requested by user + amrex::Vector field_names; + // Int Fields to be sampled - requested by user + amrex::Vector int_field_names; + // Derived fields to be sampled - requested by user + amrex::Vector derived_field_names; + + { + amrex::ParmParse pp(m_label); + pp.getarr("labels", labels); + ioutils::assert_with_message( + ioutils::all_distinct(labels), + "Duplicates in " + m_label + ".labels"); + pp.getarr("fields", field_names); + ioutils::assert_with_message( + ioutils::all_distinct(field_names), + "Duplicates in " + m_label + ".fields"); + pp.queryarr("int_fields", int_field_names); + ioutils::assert_with_message( + ioutils::all_distinct(int_field_names), + "Duplicates in " + m_label + ".int_fields"); + pp.queryarr("derived_fields", derived_field_names); + pp.query("output_frequency", m_out_freq); + pp.query("output_delay", m_out_delay); + } + + // Process field information + m_ncomp = 0; + auto& repo = m_sim.repo(); + for (const auto& fname : field_names) { + if (!repo.field_exists(fname)) { + amrex::Print() + << "WARNING: Subvolume: Non-existent field requested: " << fname + << ". This is a mistake or the requested field is a int field " + "or a derived " + "field and should be added to the int_fields/derived_fields " + "parameter" + << std::endl; + continue; + } + + auto& fld = repo.get_field(fname); + m_ncomp += fld.num_comp(); + m_fields.emplace_back(&fld); + ioutils::add_var_names(m_var_names, fld.name(), fld.num_comp()); + } + + // Process field information + m_nicomp = 0; + for (const auto& fname : int_field_names) { + if (!repo.int_field_exists(fname)) { + amrex::Print() + << "WARNING: Subvolume: Non-existent int_field requested: " + << fname + << ". This is a mistake or the requested int_field is a " + "derived " + "field and should be added to the derived_fields parameter" + << std::endl; + continue; + } + + auto& fld = repo.get_int_field(fname); + m_nicomp += fld.num_comp(); + m_int_fields.emplace_back(&fld); + ioutils::add_var_names(m_var_names, fld.name(), fld.num_comp()); + } + + // Process derived field information + if (!derived_field_names.empty()) { + m_derived_mgr->create(derived_field_names); + m_derived_mgr->filter(field_names); + m_ndcomp = m_derived_mgr->num_comp(); + m_derived_mgr->var_names(m_var_names); + } + + // Load different probe types, default probe type is line + // Should have a Subvolume base that receives the parameters for each + // int idx = 0; + // m_total_particles = 0; + for (const auto& lbl : labels) { + const std::string key = m_label + "." + lbl; + amrex::ParmParse pp1(key); + std::string stype = "Rectangular"; + + pp1.query("type", stype); + auto obj = SubvolumeBase::create(stype, m_sim); + obj->label() = lbl; + obj->subvolumetype() = stype; + // obj->id() = idx++; + obj->initialize(key); + + // m_total_particles += obj->num_points(); + m_subvolumes.emplace_back(std::move(obj)); + } +} + +void Subvolume::post_regrid_actions() +{ + BL_PROFILE("amr-wind::Subvolume::post_regrid_actions"); + + for (const auto& obj : m_subvolumes) { + obj->post_regrid_actions(); + } +} + +void Subvolume::post_advance_work() +{ + + BL_PROFILE("amr-wind::Subvolume::post_advance_work"); + const auto& time = m_sim.time(); + const int tidx = time.time_index(); + + // Skip processing if delay has not been reached + if (tidx < m_out_delay) { + return; + } + + // Skip processing if it is not an output timestep + if (!(tidx % m_out_freq == 0)) { + return; + } + + write_subvolume(); +} + +void Subvolume::write_subvolume() +{ + BL_PROFILE("amr-wind::Subvolume::write_subvolume"); + + const std::string post_dir = m_sim.io_manager().post_processing_directory(); + const std::string sampling_name = + amrex::Concatenate(m_label, m_sim.time().time_index()); + const std::string name(post_dir + "/" + sampling_name); + + const auto time = m_sim.time().new_time(); + const auto itime = m_sim.time().time_index(); + const auto n_out = m_ncomp + m_nicomp + m_ndcomp; + + // Create scratch field for derived quantities + auto scr_ptr = m_sim.repo().create_scratch_field(amrex::max(1, m_ndcomp)); + // Populate it + if (m_ndcomp > 0) { + (*m_derived_mgr)(*scr_ptr, 0); + } + + for (const auto& sv : m_subvolumes) { + + const auto lev = sv->lev(); + const auto ba = sv->box_array(); + + amrex::DistributionMapping dm(ba); + amrex::MultiFab mf_sv(ba, dm, n_out, 0); + + amrex::MultiFab mf_all_samelev( + m_sim.mesh().boxArray(lev), m_sim.mesh().DistributionMap(lev), + n_out, 0); + + int icomp = 0; + for (auto* fld : m_fields) { + amrex::MultiFab::Copy( + mf_all_samelev, (*fld)(lev), 0, icomp, fld->num_comp(), 0); + icomp += fld->num_comp(); + } + + for (auto* fld : m_int_fields) { + amrex::MultiFab::Copy( + mf_all_samelev, amrex::ToMultiFab((*fld)(lev)), 0, icomp, + fld->num_comp(), 0); + icomp += fld->num_comp(); + } + + // Contribute derived quantities to mf_all_samelev + if (m_ndcomp > 0) { + amrex::MultiFab::Copy( + mf_all_samelev, (*scr_ptr)(lev), 0, icomp, m_ndcomp, 0); + } + + mf_sv.ParallelCopy(mf_all_samelev, 0, 0, AMREX_SPACEDIM, 0, 0); + + std::string sv_label = name + "_" + sv->label(); + std::string subvol_filename = + amrex::Concatenate(sv_label, m_sim.time().time_index(), 5); + ; + + amrex::Print() << "Writing subvolume into " << subvol_filename + << std::endl; + WriteSingleLevelPlotfile( + subvol_filename, mf_sv, m_var_names, m_sim.mesh().Geom(lev), time, + itime); + } +} + +} // namespace amr_wind::subvolume diff --git a/amr-wind/utilities/subvolume/SubvolumeBase.H b/amr-wind/utilities/subvolume/SubvolumeBase.H new file mode 100644 index 0000000000..4338cccf48 --- /dev/null +++ b/amr-wind/utilities/subvolume/SubvolumeBase.H @@ -0,0 +1,53 @@ +#ifndef SUBVOLUMEBASE_H +#define SUBVOLUMEBASE_H + +#include +#include "amr-wind/core/Factory.H" + +namespace amr_wind { + +class CFDSim; + +namespace subvolume { + +/** Abstract representation of subvolume constraints to sample flow data + * \ingroup subvolume + * + * This class defines the interface by which the positions of the subvolumes + * are defined and access from the Subvolume class. All subvolume definitions + * must be sub-classes of this base class. + */ +class SubvolumeBase : public Factory +{ +public: + static std::string base_identifier() { return "SubvolumeBase"; } + + ~SubvolumeBase() override = default; + + //! Name used to refer to this sampler (e.g., myline1) + virtual std::string label() const = 0; + virtual std::string& label() = 0; + + //! Class name of this sampler (e.g., Rectangular) + virtual std::string subvolumetype() const = 0; + + //! Read inputs and perform initialization actions + virtual void initialize(const std::string& key) = 0; + + //! Check inputs and prepare for output + virtual void evaluate_inputs() = 0; + + //! Run actions after regrid + virtual void post_regrid_actions() {} + + //! Level that the subvolume corresponds to + virtual int lev() const { return 0; } + + //! BoxArray that the subvolume corresponds to + virtual amrex::BoxArray box_array() const { return amrex::BoxArray(0); } +}; + +} // namespace subvolume +} // namespace amr_wind + +#endif /* SUBVOLUMEBASE_H */ From 9c1153dc1111166b429b9ff6754225770d130f4f Mon Sep 17 00:00:00 2001 From: Michael Kuhn Date: Mon, 31 Mar 2025 11:53:19 -0600 Subject: [PATCH 2/8] move post_regrid upstream, plus a little more --- amr-wind/utilities/subvolume/RectangularSubvolume.H | 2 -- amr-wind/utilities/subvolume/RectangularSubvolume.cpp | 11 ++++------- amr-wind/utilities/subvolume/SubvolumeBase.H | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/amr-wind/utilities/subvolume/RectangularSubvolume.H b/amr-wind/utilities/subvolume/RectangularSubvolume.H index 8ee4db1fc0..43e3a502b5 100644 --- a/amr-wind/utilities/subvolume/RectangularSubvolume.H +++ b/amr-wind/utilities/subvolume/RectangularSubvolume.H @@ -32,8 +32,6 @@ public: //! quantities for output steps void evaluate_inputs() override; - void post_regrid_actions() override { evaluate_inputs(); } - //! Name of this subvolume object std::string label() const override { return m_label; } std::string& label() override { return m_label; } diff --git a/amr-wind/utilities/subvolume/RectangularSubvolume.cpp b/amr-wind/utilities/subvolume/RectangularSubvolume.cpp index 39a46253c3..42c5e90722 100644 --- a/amr-wind/utilities/subvolume/RectangularSubvolume.cpp +++ b/amr-wind/utilities/subvolume/RectangularSubvolume.cpp @@ -27,9 +27,6 @@ void RectangularSubvolume::initialize(const std::string& key) void RectangularSubvolume::evaluate_inputs() { - - int lev_for_sub = 0; - bool found = false; const auto& geom = m_sim.mesh().Geom(); for (int i = 0; i < m_sim.repo().num_active_levels(); i++) { @@ -41,9 +38,8 @@ void RectangularSubvolume::evaluate_inputs() std::abs(m_dx_vec[2] - geom[i].CellSize(2)) < constants::LOOSE_TOL) { - /* amrex::Print() << "Resolution specified matches that of level - " - << i << std::endl; */ + amrex::Print() << "Resolution specified matches that of level " + << i << std::endl; found = true; m_lev_for_sub = i; } @@ -98,7 +94,8 @@ void RectangularSubvolume::evaluate_inputs() amrex::Abort("Box requested is larger than the existing domain"); } - amrex::IntVect chunk_size(m_chunk_size_vec[0], m_chunk_size_vec[1], m_chunk_size_vec[2]); + amrex::IntVect chunk_size( + m_chunk_size_vec[0], m_chunk_size_vec[1], m_chunk_size_vec[2]); amrex::BoxArray ba(bx); ba.maxSize(chunk_size); diff --git a/amr-wind/utilities/subvolume/SubvolumeBase.H b/amr-wind/utilities/subvolume/SubvolumeBase.H index 4338cccf48..386e9079e6 100644 --- a/amr-wind/utilities/subvolume/SubvolumeBase.H +++ b/amr-wind/utilities/subvolume/SubvolumeBase.H @@ -38,7 +38,7 @@ public: virtual void evaluate_inputs() = 0; //! Run actions after regrid - virtual void post_regrid_actions() {} + virtual void post_regrid_actions() { evaluate_inputs(); } //! Level that the subvolume corresponds to virtual int lev() const { return 0; } From cbe764c6dc8582ef5f57b5e1afe991c23c940652 Mon Sep 17 00:00:00 2001 From: Michael Kuhn Date: Mon, 31 Mar 2025 12:12:47 -0600 Subject: [PATCH 3/8] comments and print statements --- .../subvolume/RectangularSubvolume.H | 6 +-- .../subvolume/RectangularSubvolume.cpp | 38 +++++++++++++------ amr-wind/utilities/subvolume/Subvolume.cpp | 22 ++++++++--- 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/amr-wind/utilities/subvolume/RectangularSubvolume.H b/amr-wind/utilities/subvolume/RectangularSubvolume.H index 43e3a502b5..535ef77679 100644 --- a/amr-wind/utilities/subvolume/RectangularSubvolume.H +++ b/amr-wind/utilities/subvolume/RectangularSubvolume.H @@ -8,9 +8,9 @@ namespace amr_wind::subvolume { /** Get subvolume defined by 3D rectangle * \ingroup subvolume * - * Defines probes along a line defined by `start` and `end` coordinates and - * divides it into equal segments as determined by `num_points`. The length of - * each segment is given by \f[ (end - start) / (num_points - 1) \f] + * Defines volume region with origin, number of points in each direction, and + * target mesh resolution in each direction. Also has an optional parameter + * regarding the data organization, which is the chunk size. */ class RectangularSubvolume : public SubvolumeBase::Register diff --git a/amr-wind/utilities/subvolume/RectangularSubvolume.cpp b/amr-wind/utilities/subvolume/RectangularSubvolume.cpp index 42c5e90722..0d67f86171 100644 --- a/amr-wind/utilities/subvolume/RectangularSubvolume.cpp +++ b/amr-wind/utilities/subvolume/RectangularSubvolume.cpp @@ -38,8 +38,10 @@ void RectangularSubvolume::evaluate_inputs() std::abs(m_dx_vec[2] - geom[i].CellSize(2)) < constants::LOOSE_TOL) { - amrex::Print() << "Resolution specified matches that of level " - << i << std::endl; + amrex::Print() + << "RectangularSubvolume " + m_label + + ": Resolution specified matches that of level " + << i << std::endl; found = true; m_lev_for_sub = i; } @@ -48,7 +50,9 @@ void RectangularSubvolume::evaluate_inputs() if (!found) { amrex::Abort( - "Resolution specified for subvolume does not match the resolution " + "RectangularSubvolume " + m_label + + ": Resolution specified for subvolume does not match the " + "resolution " "of any of the mesh levels."); } @@ -65,20 +69,26 @@ void RectangularSubvolume::evaluate_inputs() (m_origin[2] - geom[m_lev_for_sub].ProbLo(2)) * 1.0001 / m_dx_vec[2]); found = false; - if (std::abs(geom[lev_for_sub].ProbLo(0) + i0 * m_dx_vec[0] - m_origin[0]) < + if (std::abs( + geom[m_lev_for_sub].ProbLo(0) + i0 * m_dx_vec[0] - m_origin[0]) < constants::LOOSE_TOL && - std::abs(geom[lev_for_sub].ProbLo(1) + i0 * m_dx_vec[1] - m_origin[1]) < + std::abs( + geom[m_lev_for_sub].ProbLo(1) + i0 * m_dx_vec[1] - m_origin[1]) < constants::LOOSE_TOL && - std::abs(geom[lev_for_sub].ProbLo(2) + i0 * m_dx_vec[2] - m_origin[2]) < + std::abs( + geom[m_lev_for_sub].ProbLo(2) + i0 * m_dx_vec[2] - m_origin[2]) < constants::LOOSE_TOL) { - amrex::Print() << "Specified origin is the lower left corner of cell " - << amrex::IntVect(i0, j0, k0) << std::endl; + amrex::Print() + << "RectangularSubvolume " + m_label + + ": Specified origin is the lower left corner of cell " + << amrex::IntVect(i0, j0, k0) << std::endl; found = true; } if (!found) { amrex::Abort( - "Origin specified does not correspond to a node at this level."); + "RectangularSubvolume " + m_label + + ": Origin specified does not correspond to a node at this level."); } amrex::Box domain(geom[m_lev_for_sub].Domain()); @@ -88,10 +98,13 @@ void RectangularSubvolume::evaluate_inputs() amrex::IntVect( i0 + m_npts_vec[0] - 1, j0 + m_npts_vec[1] - 1, k0 + m_npts_vec[2] - 1)); - amrex::Print() << "Box requested is " << bx << std::endl; + amrex::Print() << "RectangularSubvolume " + m_label + ": Box requested is " + << bx << std::endl; if (!domain.contains(bx)) { - amrex::Abort("Box requested is larger than the existing domain"); + amrex::Abort( + "RectangularSubvolume " + m_label + + ": Box requested is larger than the existing domain"); } amrex::IntVect chunk_size( @@ -100,7 +113,8 @@ void RectangularSubvolume::evaluate_inputs() amrex::BoxArray ba(bx); ba.maxSize(chunk_size); - amrex::Print() << "BoxArray is " << ba << std::endl; + amrex::Print() << "RectangularSubvolume " + m_label + ": BoxArray is " << ba + << std::endl; m_ba = ba; } diff --git a/amr-wind/utilities/subvolume/Subvolume.cpp b/amr-wind/utilities/subvolume/Subvolume.cpp index 05681e919b..6b2fbd44ae 100644 --- a/amr-wind/utilities/subvolume/Subvolume.cpp +++ b/amr-wind/utilities/subvolume/Subvolume.cpp @@ -99,10 +99,7 @@ void Subvolume::initialize() m_derived_mgr->var_names(m_var_names); } - // Load different probe types, default probe type is line - // Should have a Subvolume base that receives the parameters for each - // int idx = 0; - // m_total_particles = 0; + // Load Subvolumes, only type is Rectangular right now for (const auto& lbl : labels) { const std::string key = m_label + "." + lbl; amrex::ParmParse pp1(key); @@ -112,10 +109,8 @@ void Subvolume::initialize() auto obj = SubvolumeBase::create(stype, m_sim); obj->label() = lbl; obj->subvolumetype() = stype; - // obj->id() = idx++; obj->initialize(key); - // m_total_particles += obj->num_points(); m_subvolumes.emplace_back(std::move(obj)); } } @@ -169,6 +164,21 @@ void Subvolume::write_subvolume() (*m_derived_mgr)(*scr_ptr, 0); } + // Current approach + // - Populate scratch field only for sake of derived quantities + // - Loop through subvolumes + // -- Copy fields of interest to mf of entire level + // -- Then copy from this mf to output mf_sv + + // Alternative way of doing this: + // - Loop through subvolumes to get levels of all subvolumes + // - Loop through these valid levels + // -- Copy fields of interest to scratch field, now used for all outputs + // - Loop through subvolumes again + // -- Copy from scratch field to output mf_sv + // ** would prevent a lot of redundant copies if many subvolumes are on the + // same level + for (const auto& sv : m_subvolumes) { const auto lev = sv->lev(); From 778b7a5ac599724bd64fee3eaf8da1e8b5e39955 Mon Sep 17 00:00:00 2001 From: Michael Kuhn Date: Thu, 10 Apr 2025 14:24:15 -0600 Subject: [PATCH 4/8] fix init, simplify output file, add reg test (not sure how to evaluate) --- amr-wind/utilities/subvolume/CMakeLists.txt | 1 + amr-wind/utilities/subvolume/Subvolume.cpp | 5 +- amr-wind/utilities/subvolume/SubvolumeBase.H | 5 +- test/CMakeLists.txt | 1 + .../abl_subvolume/abl_subvolume.inp | 116 ++++++++++++++++++ 5 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 test/test_files/abl_subvolume/abl_subvolume.inp diff --git a/amr-wind/utilities/subvolume/CMakeLists.txt b/amr-wind/utilities/subvolume/CMakeLists.txt index 9fee1a83f2..fa2ad7779d 100644 --- a/amr-wind/utilities/subvolume/CMakeLists.txt +++ b/amr-wind/utilities/subvolume/CMakeLists.txt @@ -2,4 +2,5 @@ target_sources(${amr_wind_lib_name} PRIVATE Subvolume.cpp + RectangularSubvolume.cpp ) diff --git a/amr-wind/utilities/subvolume/Subvolume.cpp b/amr-wind/utilities/subvolume/Subvolume.cpp index 6b2fbd44ae..b7739fdb4b 100644 --- a/amr-wind/utilities/subvolume/Subvolume.cpp +++ b/amr-wind/utilities/subvolume/Subvolume.cpp @@ -110,6 +110,7 @@ void Subvolume::initialize() obj->label() = lbl; obj->subvolumetype() = stype; obj->initialize(key); + obj->post_init_actions(); m_subvolumes.emplace_back(std::move(obj)); } @@ -149,9 +150,7 @@ void Subvolume::write_subvolume() BL_PROFILE("amr-wind::Subvolume::write_subvolume"); const std::string post_dir = m_sim.io_manager().post_processing_directory(); - const std::string sampling_name = - amrex::Concatenate(m_label, m_sim.time().time_index()); - const std::string name(post_dir + "/" + sampling_name); + const std::string name(post_dir + "/" + m_label); const auto time = m_sim.time().new_time(); const auto itime = m_sim.time().time_index(); diff --git a/amr-wind/utilities/subvolume/SubvolumeBase.H b/amr-wind/utilities/subvolume/SubvolumeBase.H index 386e9079e6..d9cda8ab90 100644 --- a/amr-wind/utilities/subvolume/SubvolumeBase.H +++ b/amr-wind/utilities/subvolume/SubvolumeBase.H @@ -31,12 +31,15 @@ public: //! Class name of this sampler (e.g., Rectangular) virtual std::string subvolumetype() const = 0; - //! Read inputs and perform initialization actions + //! Read inputs virtual void initialize(const std::string& key) = 0; //! Check inputs and prepare for output virtual void evaluate_inputs() = 0; + //! Run actions after initialize + virtual void post_init_actions() { evaluate_inputs(); } + //! Run actions after regrid virtual void post_regrid_actions() { evaluate_inputs(); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0bc655d433..52b8208c31 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -199,6 +199,7 @@ add_test_re(abl_ksgsm84_godunov) add_test_re(abl_mol_cn) add_test_re(abl_mol_explicit) add_test_re(abl_sampling) +add_test_re(abl_subvolume) add_test_re(abl_stable) add_test_re(abl_unstable) add_test_re(abl_unstable_constant_wall_model) diff --git a/test/test_files/abl_subvolume/abl_subvolume.inp b/test/test_files/abl_subvolume/abl_subvolume.inp new file mode 100644 index 0000000000..34a963a81b --- /dev/null +++ b/test/test_files/abl_subvolume/abl_subvolume.inp @@ -0,0 +1,116 @@ +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SIMULATION STOP # +#.......................................# +time.stop_time = 22000.0 # Max (simulated) time to evolve +time.max_step = 10 # Max number of time steps + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# TIME STEP COMPUTATION # +#.......................................# +time.fixed_dt = 0.5 # Use this constant dt if > 0 +time.cfl = 0.95 # CFL factor + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# INPUT AND OUTPUT # +#.......................................# +time.plot_interval = 10 # Steps between plot files +time.checkpoint_interval = 5 # Steps between checkpoint files + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PHYSICS # +#.......................................# +incflo.gravity = 0. 0. -9.81 # Gravitational force (3D) +incflo.density = 1.0 # Reference density + +io.derived_outputs = mag_vorticity "components(velocity,0,1)" "grad(temperature)" + +incflo.use_godunov = 1 +incflo.godunov_type = ppm +incflo.diffusion_type = 2 +transport.viscosity = 1.0e-5 +transport.laminar_prandtl = 0.7 +transport.turbulent_prandtl = 0.3333 +transport.reference_temperature = 300.0 +turbulence.model = Smagorinsky +Smagorinsky_coeffs.Cs = 0.135 + + +incflo.physics = ABL +ICNS.source_terms = BoussinesqBuoyancy CoriolisForcing ABLForcing +CoriolisForcing.latitude = 41.3 +ABLForcing.abl_forcing_height = 90 + +incflo.velocity = 6.128355544951824 5.142300877492314 0.0 + +ABL.temperature_heights = 650.0 750.0 1000.0 +ABL.temperature_values = 300.0 308.0 308.75 + +ABL.kappa = .41 +ABL.surface_roughness_z0 = 0.15 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# ADAPTIVE MESH REFINEMENT # +#.......................................# +amr.n_cell = 48 48 48 # Grid cells at coarsest AMRlevel +amr.max_level = 1 # Max AMR level in hierarchy +amr.max_grid_size = 8 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# GEOMETRY # +#.......................................# +geometry.prob_lo = 0. 0. 0. # Lo corner coordinates +geometry.prob_hi = 1000. 1000. 1000. # Hi corner coordinates +geometry.is_periodic = 1 1 0 # Periodicity x y z (0/1) + +# Boundary conditions +zlo.type = "wall_model" + +zhi.type = "slip_wall" +zhi.temperature_type = "fixed_gradient" +zhi.temperature = 0.003 # tracer is used to specify potential temperature gradient + +tagging.labels = box +tagging.box.type = GeometryRefinement +tagging.box.shapes = b0 +tagging.box.level = 0 + +tagging.box.b0.type = box +tagging.box.b0.origin = 400.0 400.0 400.0 +tagging.box.b0.xaxis = 100.0 0.0 0.0 +tagging.box.b0.yaxis = 0.0 100.0 0.0 +tagging.box.b0.zaxis = 0.0 0.0 100.0 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# VERBOSITY # +#.......................................# +incflo.verbose = 0 # incflo_level + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SAMPLING # +#.......................................# +incflo.post_processing = subvol1 subvol2 +subvol1.output_frequency = 1 +subvol1.fields = velocity +subvol1.int_fields = mask_cell +subvol1.derived_fields = mag_vorticity "components(velocity,0,1)" "grad(temperature)" "grad(density)" +subvol1.labels = vol1 vol2 +subvol1.type = Subvolume +subvol1.vol1.type = Rectangular +subvol1.vol1.origin = 395.8333333333346 395.8333333333346 395.8333333333346 +subvol1.vol1.num_points = 2 2 4 +subvol1.vol1.dx_vec = 10.416666666666666667 10.416666666666666667 10.416666666666666667 +subvol1.vol2.type = Rectangular +subvol1.vol2.origin = 447.9166666681 447.9166666681 447.9166666681 +subvol1.vol2.num_points = 2 2 4 +subvol1.vol2.dx_vec = 10.416666666666666667 10.416666666666666667 10.416666666666666667 + +subvol2.output_frequency = 2 +subvol2.fields = velocity +subvol2.int_fields = mask_cell +subvol2.derived_fields = q_criterion_nondim +subvol2.labels = vol3 +subvol2.type = Subvolume +subvol2.vol3.type = Rectangular +subvol2.vol3.origin = 0. 0. 0. +subvol2.vol3.num_points = 24 24 12 +subvol2.vol3.dx_vec = 20.8333333333 20.83333333333 20.8333333333 \ No newline at end of file From 52c0ceece3012a0a13af8bfe82456a4234c0d75b Mon Sep 17 00:00:00 2001 From: Michael Kuhn Date: Thu, 10 Apr 2025 14:44:52 -0600 Subject: [PATCH 5/8] once dx has been confirmed, use the actual mesh dx - loose_tol is too tight for input file specification, 4 decimal places should be enough --- .../subvolume/RectangularSubvolume.cpp | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/amr-wind/utilities/subvolume/RectangularSubvolume.cpp b/amr-wind/utilities/subvolume/RectangularSubvolume.cpp index 0d67f86171..7db2d85b98 100644 --- a/amr-wind/utilities/subvolume/RectangularSubvolume.cpp +++ b/amr-wind/utilities/subvolume/RectangularSubvolume.cpp @@ -31,12 +31,9 @@ void RectangularSubvolume::evaluate_inputs() const auto& geom = m_sim.mesh().Geom(); for (int i = 0; i < m_sim.repo().num_active_levels(); i++) { if (!found) { - if (std::abs(m_dx_vec[0] - geom[i].CellSize(0)) < - constants::LOOSE_TOL && - std::abs(m_dx_vec[1] - geom[i].CellSize(1)) < - constants::LOOSE_TOL && - std::abs(m_dx_vec[2] - geom[i].CellSize(2)) < - constants::LOOSE_TOL) { + if (std::abs(m_dx_vec[0] - geom[i].CellSize(0)) < 1e-4 && + std::abs(m_dx_vec[1] - geom[i].CellSize(1)) < 1e-4 && + std::abs(m_dx_vec[2] - geom[i].CellSize(2)) < 1e-4) { amrex::Print() << "RectangularSubvolume " + m_label + @@ -62,22 +59,25 @@ void RectangularSubvolume::evaluate_inputs() // division of two reals --> integer will do a floor // ************************************************************** int i0 = static_cast( - (m_origin[0] - geom[m_lev_for_sub].ProbLo(0)) * 1.0001 / m_dx_vec[0]); + (m_origin[0] - geom[m_lev_for_sub].ProbLo(0)) * 1.0001 / + geom[m_lev_for_sub].CellSize(0)); int j0 = static_cast( - (m_origin[1] - geom[m_lev_for_sub].ProbLo(1)) * 1.0001 / m_dx_vec[1]); + (m_origin[1] - geom[m_lev_for_sub].ProbLo(1)) * 1.0001 / + geom[m_lev_for_sub].CellSize(1)); int k0 = static_cast( - (m_origin[2] - geom[m_lev_for_sub].ProbLo(2)) * 1.0001 / m_dx_vec[2]); + (m_origin[2] - geom[m_lev_for_sub].ProbLo(2)) * 1.0001 / + geom[m_lev_for_sub].CellSize(2)); found = false; if (std::abs( - geom[m_lev_for_sub].ProbLo(0) + i0 * m_dx_vec[0] - m_origin[0]) < - constants::LOOSE_TOL && + geom[m_lev_for_sub].ProbLo(0) + + i0 * geom[m_lev_for_sub].CellSize(0) - m_origin[0]) < 1e-4 && std::abs( - geom[m_lev_for_sub].ProbLo(1) + i0 * m_dx_vec[1] - m_origin[1]) < - constants::LOOSE_TOL && + geom[m_lev_for_sub].ProbLo(1) + + j0 * geom[m_lev_for_sub].CellSize(1) - m_origin[1]) < 1e-4 && std::abs( - geom[m_lev_for_sub].ProbLo(2) + i0 * m_dx_vec[2] - m_origin[2]) < - constants::LOOSE_TOL) { + geom[m_lev_for_sub].ProbLo(2) + + k0 * geom[m_lev_for_sub].CellSize(2) - m_origin[2]) < 1e-4) { amrex::Print() << "RectangularSubvolume " + m_label + ": Specified origin is the lower left corner of cell " From 889346540213812c7f31ce48a829bd9d8745d02d Mon Sep 17 00:00:00 2001 From: Michael Kuhn Date: Thu, 10 Apr 2025 14:47:21 -0600 Subject: [PATCH 6/8] modify inputs to be more relaxed --- test/test_files/abl_subvolume/abl_subvolume.inp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/test_files/abl_subvolume/abl_subvolume.inp b/test/test_files/abl_subvolume/abl_subvolume.inp index 34a963a81b..d32422406c 100644 --- a/test/test_files/abl_subvolume/abl_subvolume.inp +++ b/test/test_files/abl_subvolume/abl_subvolume.inp @@ -96,13 +96,13 @@ subvol1.derived_fields = mag_vorticity "components(velocity,0,1)" "grad(tem subvol1.labels = vol1 vol2 subvol1.type = Subvolume subvol1.vol1.type = Rectangular -subvol1.vol1.origin = 395.8333333333346 395.8333333333346 395.8333333333346 +subvol1.vol1.origin = 395.8333 395.8333 395.8333 subvol1.vol1.num_points = 2 2 4 -subvol1.vol1.dx_vec = 10.416666666666666667 10.416666666666666667 10.416666666666666667 +subvol1.vol1.dx_vec = 10.4167 10.4167 10.4167 subvol1.vol2.type = Rectangular -subvol1.vol2.origin = 447.9166666681 447.9166666681 447.9166666681 +subvol1.vol2.origin = 447.9167 447.9167 447.9167 subvol1.vol2.num_points = 2 2 4 -subvol1.vol2.dx_vec = 10.416666666666666667 10.416666666666666667 10.416666666666666667 +subvol1.vol2.dx_vec = 10.4167 10.4167 10.4167 subvol2.output_frequency = 2 subvol2.fields = velocity @@ -113,4 +113,4 @@ subvol2.type = Subvolume subvol2.vol3.type = Rectangular subvol2.vol3.origin = 0. 0. 0. subvol2.vol3.num_points = 24 24 12 -subvol2.vol3.dx_vec = 20.8333333333 20.83333333333 20.8333333333 \ No newline at end of file +subvol2.vol3.dx_vec = 20.8333 20.8333 20.8333 \ No newline at end of file From 55a7ff911c48be1c9a63080453af6b0a51caa782 Mon Sep 17 00:00:00 2001 From: Michael Kuhn Date: Thu, 10 Apr 2025 15:22:21 -0600 Subject: [PATCH 7/8] update header guard --- amr-wind/utilities/subvolume/RectangularSubvolume.H | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/amr-wind/utilities/subvolume/RectangularSubvolume.H b/amr-wind/utilities/subvolume/RectangularSubvolume.H index 535ef77679..8a9f10c6aa 100644 --- a/amr-wind/utilities/subvolume/RectangularSubvolume.H +++ b/amr-wind/utilities/subvolume/RectangularSubvolume.H @@ -1,5 +1,5 @@ -#ifndef LINESAMPLER_H -#define LINESAMPLER_H +#ifndef RECTANGULARSUBVOLUME_H +#define RECTANGULARSUBVOLUME_H #include "amr-wind/utilities/subvolume/SubvolumeBase.H" @@ -60,4 +60,4 @@ protected: } // namespace amr_wind::subvolume -#endif /* LINESAMPLER_H */ +#endif /* RECTANGULARSUBVOLUME_H */ From b6eb107cf931bfef7e18c6b5f4f704dfaf4a1f48 Mon Sep 17 00:00:00 2001 From: Michael Kuhn Date: Thu, 12 Jun 2025 15:36:42 -0600 Subject: [PATCH 8/8] update to adhere to new postprocessing io parameter framework --- amr-wind/utilities/subvolume/Subvolume.H | 11 +++------ amr-wind/utilities/subvolume/Subvolume.cpp | 26 ++-------------------- 2 files changed, 5 insertions(+), 32 deletions(-) diff --git a/amr-wind/utilities/subvolume/Subvolume.H b/amr-wind/utilities/subvolume/Subvolume.H index 4e05adf7e5..b470af1760 100644 --- a/amr-wind/utilities/subvolume/Subvolume.H +++ b/amr-wind/utilities/subvolume/Subvolume.H @@ -44,9 +44,10 @@ public: void post_regrid_actions() override; //! Get chunks and output to disk - void post_advance_work() override; + void output_actions() override; - void write_subvolume(); + //! Actions to do at end of every time step + void post_advance_work() override {}; const amrex::Vector& var_names() const { return m_var_names; } @@ -83,12 +84,6 @@ private: // number of derived field components int m_ndcomp{0}; - - //! Frequency of data output - int m_out_freq{100}; - - //! Delay number of timestep before output - int m_out_delay{0}; }; } // namespace amr_wind::subvolume diff --git a/amr-wind/utilities/subvolume/Subvolume.cpp b/amr-wind/utilities/subvolume/Subvolume.cpp index b7739fdb4b..5342073643 100644 --- a/amr-wind/utilities/subvolume/Subvolume.cpp +++ b/amr-wind/utilities/subvolume/Subvolume.cpp @@ -46,8 +46,6 @@ void Subvolume::initialize() ioutils::all_distinct(int_field_names), "Duplicates in " + m_label + ".int_fields"); pp.queryarr("derived_fields", derived_field_names); - pp.query("output_frequency", m_out_freq); - pp.query("output_delay", m_out_delay); } // Process field information @@ -125,29 +123,9 @@ void Subvolume::post_regrid_actions() } } -void Subvolume::post_advance_work() +void Subvolume::output_actions() { - - BL_PROFILE("amr-wind::Subvolume::post_advance_work"); - const auto& time = m_sim.time(); - const int tidx = time.time_index(); - - // Skip processing if delay has not been reached - if (tidx < m_out_delay) { - return; - } - - // Skip processing if it is not an output timestep - if (!(tidx % m_out_freq == 0)) { - return; - } - - write_subvolume(); -} - -void Subvolume::write_subvolume() -{ - BL_PROFILE("amr-wind::Subvolume::write_subvolume"); + BL_PROFILE("amr-wind::Subvolume::output_actions"); const std::string post_dir = m_sim.io_manager().post_processing_directory(); const std::string name(post_dir + "/" + m_label);