Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sampling volume #959

Merged
merged 7 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions amr-wind/utilities/sampling/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ target_sources(${amr_wind_lib_name}
KineticEnergy.cpp
Enstrophy.cpp
FreeSurface.cpp
VolumeSampler.cpp
WaveEnergy.cpp
)
63 changes: 63 additions & 0 deletions amr-wind/utilities/sampling/VolumeSampler.H
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#ifndef VOLUMESAMPLER_H
#define VOLUMESAMPLER_H

#include "amr-wind/utilities/sampling/SamplerBase.H"

namespace amr_wind::sampling {

/** Sample data on uniform grids
* \ingroup sampling
*
* Defines probe locations on a volume defined by an
* `axis` that originates from the point `origin`.
* The resolution of the volume is defined by the vector npts_dir.
*
*/
class VolumeSampler : public SamplerBase::Register<VolumeSampler>
{
public:
static std::string identifier() { return "VolumeSampler"; }

explicit VolumeSampler(const CFDSim& /*unused*/);

~VolumeSampler() override;

/** Read user inputs and initialize the sampling object
*
* \param key Prefix used to parse inputs from file
*/
void initialize(const std::string& key) override;

//! Populate and return a vector of probe locations to be sampled
void sampling_locations(SampleLocType& /*locs*/) const override;

void
define_netcdf_metadata(const ncutils::NCGroup& /*unused*/) const override;
void
populate_netcdf_metadata(const ncutils::NCGroup& /*unused*/) const override;

//! Name of this sampling object
std::string label() const override { return m_label; }
std::string& label() override { return m_label; }

//! Unique identifier for this set of probe locations
int id() const override { return m_id; }
int& id() override { return m_id; }

//! Number of probe locations along the line
int num_points() const override { return m_npts; }

private:
amrex::Vector<amrex::Real> m_axis;
amrex::Vector<amrex::Real> m_origin;
amrex::Vector<int> m_npts_dir;

std::string m_label;

int m_id{-1};
int m_npts{0};
};

} // namespace amr_wind::sampling

#endif /* VOLUMESAMPLER_H */
79 changes: 79 additions & 0 deletions amr-wind/utilities/sampling/VolumeSampler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include <limits>

#include "amr-wind/utilities/sampling/VolumeSampler.H"

#include "AMReX_ParmParse.H"

namespace amr_wind::sampling {

VolumeSampler::VolumeSampler(const CFDSim& /*unused*/) {}

VolumeSampler::~VolumeSampler() = default;

void VolumeSampler::initialize(const std::string& key)
{
amrex::ParmParse pp(key);

pp.getarr("axis", m_axis);
pp.getarr("origin", m_origin);
pp.getarr("num_points", m_npts_dir);
AMREX_ALWAYS_ASSERT(static_cast<int>(m_axis.size()) == AMREX_SPACEDIM);
AMREX_ALWAYS_ASSERT(static_cast<int>(m_origin.size()) == AMREX_SPACEDIM);
AMREX_ALWAYS_ASSERT(static_cast<int>(m_npts_dir.size()) == AMREX_SPACEDIM);

// Update total number of points
const size_t tmp = m_npts_dir[0] * m_npts_dir[1] * m_npts_dir[2];

Check warning on line 25 in amr-wind/utilities/sampling/VolumeSampler.cpp

View workflow job for this annotation

GitHub Actions / Lint-clang-tidy

performing an implicit widening conversion to type 'const size_t' (aka 'const unsigned long') of a multiplication performed in type 'int' [bugprone-implicit-widening-of-multiplication-result]
if (tmp > static_cast<size_t>(std::numeric_limits<int>::max())) {
amrex::Abort(
"VolumeSampler: Plane definition " + key +
tonyinme marked this conversation as resolved.
Show resolved Hide resolved
" exceeds 32-bit integer limits");
}
m_npts = static_cast<int>(tmp);
}

void VolumeSampler::sampling_locations(SampleLocType& locs) const
{
locs.resize(m_npts);

amrex::Array<amrex::Real, AMREX_SPACEDIM> dx;
tonyinme marked this conversation as resolved.
Show resolved Hide resolved

for (int d = 0; d < AMREX_SPACEDIM; ++d) {
dx[d] = m_axis[d] / m_npts_dir[d];
}

int idx = 0;
for (int k = 0; k < m_npts_dir[2]; ++k) {
for (int j = 0; j < m_npts_dir[1]; ++j) {
for (int i = 0; i < m_npts_dir[0]; ++i) {
for (int d = 0; d < AMREX_SPACEDIM; ++d) {
locs[idx][0] = m_origin[0] + dx[0] * i;
tonyinme marked this conversation as resolved.
Show resolved Hide resolved
locs[idx][1] = m_origin[1] + dx[1] * j;
locs[idx][2] = m_origin[2] + dx[2] * k;
}
++idx;
}
}
}
}

#ifdef AMR_WIND_USE_NETCDF
void VolumeSampler::define_netcdf_metadata(const ncutils::NCGroup& grp) const
{
const std::vector<int> ijk{m_npts_dir[0], m_npts_dir[1], m_npts_dir[2]};
grp.put_attr("sampling_type", identifier());
grp.put_attr("ijk_dims", ijk);
grp.put_attr("origin", m_origin);
grp.put_attr("axis", m_axis);
}

void VolumeSampler::populate_netcdf_metadata(const ncutils::NCGroup&) const {}
#else
void VolumeSampler::define_netcdf_metadata(
const ncutils::NCGroup& /*unused*/) const
{}
void VolumeSampler::populate_netcdf_metadata(
const ncutils::NCGroup& /*unused*/) const
{}
#endif

} // namespace amr_wind::sampling
12 changes: 12 additions & 0 deletions docs/sphinx/user/inputs_Sampling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,16 @@ Example::
The first line of the file contains the total number of probes for this set.
This is followed by the coordinates (three real numbers), one line per probe.

Sampling on a volume
`````````````````````

The ``VolumeSampler`` samples a 3D volume that starts at ``origin`` and
extends to ``axis``. The resolution in all directions is specified by
``num_points``.

Example::

sampling.volume1.type = VolumeSampler
sampling.volume1.axis = 3.0 1.0 0.5
tonyinme marked this conversation as resolved.
Show resolved Hide resolved
sampling.volume1.origin = 0.0 0.0 -0.5
sampling.volume1.num_points = 30 10 10
Loading