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");
100 amrex::Abort(
"NetCDF time series variable " +
field_name +
109 amrex::Abort(
"Unsupported NetCDF time series rank for variable " +
111 std::to_string(
field_rank) +
". Expected rank 1 for " +
112 "uniform time-only data or rank " +
114 " for spatial data.");
120 const int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
131 amrex::Vector<NDArray<double>>
array_ts(1);
133 if (amrex::ParallelDescriptor::IOProcessor())
147 [&](
const auto&
x) { return x == file_is_cycle.front(); });
149 [&](
const auto&
x) { return x == file_cycle_length.front(); });
152 amrex::Abort(
"If one time series file in a set has a cycle, they all must, and cycle lengths must be equal");
162 if (amrex::ParallelDescriptor::IOProcessor()) {
165 amrex::Error(
"Time series data must be given at at least two times");
168 int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
170 if (!(amrex::ParallelDescriptor::IOProcessor())) {
205 const amrex::Vector<amrex::Geometry>&
geom,
206 const amrex::Vector<amrex::IntVect>&
ref_ratio) {
232 amrex::Abort(
"Time " + std::to_string(
time) +
" (mapped to " + std::to_string(
l_time)
233 +
") is not spanned by the time series for '" +
field_name +
"', which covers ["
236 +
"]. Extend the forcing file to cover the run, or give its time variable a"
237 +
" cycle_length attribute so it repeats.");
260#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
306 amrex::Interpolater*
mapper =
nullptr;
308 if (
idx_type == amrex::IndexType(amrex::IntVect(0,0,0))) {
309 mapper = &amrex::cell_cons_interp;
311 mapper = &amrex::face_cons_linear_interp;
326 const amrex::Vector<amrex::IntVect>&
ref_ratio)
const {
327 amrex::IntVect
rr(1,1,1);
328 for (
int l = 0;
l <
lev; ++
l) {
336const amrex::MultiFab*
344 "NCTimeSeries '" +
field_name +
"' was last interpolated for level "
346 +
". Call update_interpolated_to_time for this level first.");
359 amrex::Print() <<
"Reading in " <<
field_name <<
" at time index " <<
itime
364 "NetCDF time series file layout was not initialized");
372 if (amrex::ParallelDescriptor::IOProcessor()) {
373 const std::vector<MPI_Offset> shape =
array_dat[0].get_vshape();
375 shape.size() == 1 && shape[0] == 1,
376 "Uniform NetCDF time series read did not produce one value");
380 const int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
388 amrex::Vector<amrex::FArrayBox*>
NC_fabs;
389 amrex::Vector<std::string>
NC_names;
405#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
409 for ( amrex::MFIter
mfi(*
mf,
false);
mfi.isValid(); ++
mfi )
411 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 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.
double time_before
Time in ocean_times immediately before the last time interpolated to.
amrex::MultiFab * mf_interp_lev0
Multifab storing temporally interpolated data on level 0.
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::MultiFab * mf_before
Multifab to store data at time_before.
amrex::Vector< double > ocean_times
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.
double cycle_length
If a cycle, what is the cycle length?
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.
void update_interpolated_to_time(double 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, in seconds on the model clock, and fill data for level lev.
double time_after
Time in ocean_times immediately after the last time interpolated to.
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,...