5#include "AMReX_FillPatchUtil.H"
6#include "AMReX_Interpolater.H"
7#include "AMReX_ParallelDescriptor.H"
14#ifdef REMORA_USE_NETCDF
39 amrex::Print() <<
"Loading " <<
field_name <<
" from NetCDF file(s)" << std::endl;
45 if (
field_name.find(
"wind") != std::string::npos) {
64 if (amrex::ParallelDescriptor::IOProcessor())
66 if (
unit_str.find(
"days") == std::string::npos) {
67 amrex::Print() <<
"Units of ocean_time given as: " <<
unit_str << std::endl;
68 amrex::Abort(
"Units must be in days.");
82 if (amrex::ParallelDescriptor::IOProcessor())
94 "NetCDF time variable cycle_length attribute must be scalar");
103 amrex::Abort(
"NetCDF time series variable " +
field_name +
112 amrex::Abort(
"Unsupported NetCDF time series rank for variable " +
114 std::to_string(
field_rank) +
". Expected rank 1 for " +
115 "uniform time-only data or rank " +
117 " for spatial data.");
123 const int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
137 if (amrex::ParallelDescriptor::IOProcessor())
143 ocean_times.push_back((*(
array_ts[0].get_data() + nt)) * amrex::Real(60.0) * amrex::Real(60.0) * amrex::Real(24.0));
151 [&](
const auto&
x) { return x == file_is_cycle.front(); });
153 [&](
const auto&
x) { return x == file_cycle_length.front(); });
156 amrex::Abort(
"If one time series file in a set has a cycle, they all must, and cycle lengths must be equal");
166 if (amrex::ParallelDescriptor::IOProcessor()) {
169 amrex::Error(
"Time series data must be given at at least two times");
172 int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
174 if (!(amrex::ParallelDescriptor::IOProcessor())) {
209 const amrex::Vector<amrex::Geometry>&
geom,
210 const amrex::Vector<amrex::IntVect>&
ref_ratio) {
236 amrex::Abort(
"Time " + std::to_string(
time) +
" (mapped to " + std::to_string(
l_time)
237 +
") is not spanned by the time series for '" +
field_name +
"', which covers ["
240 +
"]. Extend the forcing file to cover the run, or give its time variable a"
241 +
" cycle_length attribute so it repeats.");
262#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
307 amrex::Interpolater*
mapper =
nullptr;
309 if (
idx_type == amrex::IndexType(amrex::IntVect(0,0,0))) {
310 mapper = &amrex::cell_cons_interp;
312 mapper = &amrex::face_cons_linear_interp;
327 const amrex::Vector<amrex::IntVect>&
ref_ratio)
const {
328 amrex::IntVect
rr(1,1,1);
329 for (
int l = 0;
l <
lev; ++
l) {
337const amrex::MultiFab*
354 amrex::Print() <<
"Reading in " <<
field_name <<
" at time index " <<
itime
359 "NetCDF time series file layout was not initialized");
367 if (amrex::ParallelDescriptor::IOProcessor()) {
368 const std::vector<MPI_Offset> shape =
array_dat[0].get_vshape();
370 shape.size() == 1 && shape[0] == 1,
371 "Uniform NetCDF time series read did not produce one value");
375 const int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
383 amrex::Vector<amrex::FArrayBox*>
NC_fabs;
384 amrex::Vector<std::string>
NC_names;
400#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
404 for ( amrex::MFIter
mfi(*
mf,
false);
mfi.isValid(); ++
mfi )
406 amrex::FArrayBox &
fab = (*mf)[
mfi];
constexpr amrex::Real zero
mf_h setVal(geomdata.ProbHi(2))
AMREX_ALWAYS_ASSERT(!NSPeriodic||!EWPeriodic)
void ReadNetCDFFile(const std::string &fname, amrex::Vector< std::string > names, amrex::Vector< NDArray< DType > > &arrays, bool one_time=false, int fill_time=0)
Read in data from netcdf file and save to data arrays.
std::string ReadNetCDFVarAttrStr(const std::string &fname, const std::string &var_name, const std::string &attr_name)
Helper function for reading a single variable attribute.
static PhysBCFunctNoOp null_bc_for_fill
amrex::Vector< std::unique_ptr< amrex::MultiFab > > mf_interpolated_lev
Interpolated data on each requested AMR level if save_interpolated=true.
bool is2d
Whether the field we're reading in is 2d.
void update_interpolated_to_time(amrex::Real time, int lev, amrex::MultiFab *mf_lev, const amrex::Vector< amrex::Geometry > &geom, const amrex::Vector< amrex::IntVect > &ref_ratio)
Calculate interpolated values at time and fill data for level lev.
void read_in_at_time(amrex::MultiFab *mf, int itime)
Read in data from file at time index itime and fill into mf.
amrex::Vector< int > file_itime_offset
Offset to access a particular time within its file.
amrex::MultiFab * mf_interp_lev0
Multifab storing temporally interpolated data on level 0.
amrex::Real time_after
Time in ocean_times immediately after the last time interpolated to.
amrex::Real time_before
Time in ocean_times immediately before the last time interpolated to.
bool is_cycle
Whether the time series is a cycle.
void Initialize()
Read in time array from file and allocate data arrays.
amrex::Vector< int > file_is_spatially_uniform
Whether each file stores this field as one value per time record.
amrex::Real cycle_length
If a cycle, what is the cycle length?
amrex::MultiFab * mf_before
Multifab to store data at time_before.
int i_time_before
Time index immediately before the last time interpolated to.
std::string field_name
Field name in netcdf file.
amrex::IntVect cumulative_ref_ratio(int lev, const amrex::Vector< amrex::IntVect > &ref_ratio) const
Build cumulative refinement ratio from level 0 to lev.
NCTimeSeries(const amrex::Vector< std::string > &a_file_names, const std::string a_field_name, const std::string a_time_name, const amrex::Box &a_domain, amrex::MultiFab *a_mf_var, bool a_is2d, bool a_save_interpolated)
Constructor.
amrex::Vector< std::string > file_names
File names to read from.
amrex::MultiFab * mf_after
Multifab to store data at time_after.
std::string time_name
Field name for time series in netcdf file.
amrex::Vector< int > file_for_time
File index to access a particular time.
const amrex::MultiFab * get_interpolated_mf(int lev) const
Access interpolated data saved for a specific level.
amrex::Vector< amrex::Real > ocean_times
Time points in netcdf file.
static NCFile open(const std::string &name, const int cmode=NC_NOWRITE, MPI_Comm comm=MPI_COMM_WORLD, MPI_Info info=MPI_INFO_NULL)
Open an existing file.
NDArray is the datatype designed to hold any data, including scalars, multidimensional arrays,...