4#include "AMReX_FillPatchUtil.H"
5#include "AMReX_Interpolater.H"
6#include "AMReX_ParallelDescriptor.H"
10#ifdef REMORA_USE_NETCDF
21 const std::string a_time_name,
22 const amrex::Box& a_domain,
23 amrex::MultiFab* a_mf_var,
bool a_is2d,
bool a_save_interpolated) {
24 file_names.assign(a_file_names.begin(), a_file_names.end());
35 amrex::Print() <<
"Loading " <<
field_name <<
" from NetCDF file(s)" << std::endl;
41 if (
field_name.find(
"wind") != std::string::npos) {
52 for (
int ifile = 0; ifile <
file_names.size(); ++ifile) {
53 const std::string& file_name =
file_names[ifile];
57 if (amrex::ParallelDescriptor::IOProcessor())
59 if (unit_str.find(
"days") == std::string::npos) {
60 amrex::Print() <<
"Units of ocean_time given as: " << unit_str << std::endl;
61 amrex::Abort(
"Units must be in days.");
67 amrex::Vector<RARRAY> array_ts(1);
69 if (amrex::ParallelDescriptor::IOProcessor())
71 int ntimes_io = array_ts[0].get_vshape()[0];
72 for (
int nt(0); nt < ntimes_io; nt++)
75 ocean_times.push_back((*(array_ts[0].get_data() + nt)) * amrex::Real(60.0) * amrex::Real(60.0) * amrex::Real(24.0));
83 if (amrex::ParallelDescriptor::IOProcessor()) {
86 amrex::Error(
"Time series data must be given at at least two times");
89 int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
90 amrex::ParallelDescriptor::Bcast(&ntimes,1,ioproc);
91 if (!(amrex::ParallelDescriptor::IOProcessor())) {
114 amrex::MultiFab* mf_lev,
115 const amrex::Vector<amrex::Geometry>& geom,
116 const amrex::Vector<amrex::IntVect>& ref_ratio) {
145#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
147 for (amrex::MFIter mfi(*
mf_interp_lev0,
true); mfi.isValid(); ++mfi) {
149 amrex::Box bx = mfi.growntilebox(amrex::IntVect(1-nodality[0],1-nodality[1],0));
155 amrex::Array4<amrex::Real> to_fill = mf_to_fill->array(mfi);
156 amrex::Array4<const amrex::Real> before =
mf_before->const_array(mfi);
157 amrex::Array4<const amrex::Real> after =
mf_after->const_array(mfi);
158 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
160 to_fill(i,j,k) = before(i,j,k) + (time - time_before_copy) * (after(i,j,k) - before(i,j,k)) / dt;
164 amrex::MultiFab* mf_to_fill_lev = mf_lev;
173 mf_lev->boxArray(), mf_lev->DistributionMap(), 1, mf_lev->nGrowVect());
179 amrex::MultiFab::Copy(*mf_to_fill_lev, *
mf_interp_lev0, 0, 0, 1, mf_to_fill_lev->nGrowVect());
184 amrex::Vector<amrex::BCRec> null_dom_bcs(1);
185 for (
int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
186 null_dom_bcs[0].setLo(dir, amrex::BCType::int_dir);
187 null_dom_bcs[0].setHi(dir, amrex::BCType::int_dir);
190 amrex::Interpolater* mapper =
nullptr;
191 const auto& idx_type = mf_to_fill_lev->ixType();
192 if (idx_type == amrex::IndexType(amrex::IntVect(0,0,0))) {
193 mapper = &amrex::cell_cons_interp;
195 mapper = &amrex::face_cons_linear_interp;
198 amrex::InterpFromCoarseLevel(*mf_to_fill_lev, amrex::Real(0.0), *
mf_interp_lev0,
203 mapper, null_dom_bcs, 0);
205 mf_to_fill_lev->FillBoundary(geom[lev].periodicity());
210 const amrex::Vector<amrex::IntVect>& ref_ratio)
const {
211 amrex::IntVect rr(1,1,1);
212 for (
int l = 0; l < lev; ++l) {
213 rr[0] *= ref_ratio[l][0];
214 rr[1] *= ref_ratio[l][1];
215 rr[2] *= ref_ratio[l][2];
220const amrex::MultiFab*
234 amrex::FArrayBox NC_fab;
235 amrex::Vector<amrex::FArrayBox*> NC_fabs;
236 amrex::Vector<std::string> NC_names;
237 amrex::Vector<enum NC_Data_Dims_Type> NC_dim_types;
242 amrex::Print() <<
"Reading in " <<
field_name <<
" at time index " << itime
243 <<
" from " << file_name << std::endl;
245 NC_fabs.push_back(&NC_fab) ; NC_names.push_back(
field_name);
253 BuildFABsFromNetCDFFile<amrex::FArrayBox,amrex::Real>(
domain, file_name, NC_names, NC_dim_types,
254 NC_fabs,
true, itime_offset);
257#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
261 for ( amrex::MFIter mfi(*mf,
false); mfi.isValid(); ++mfi )
263 amrex::FArrayBox &fab = (*mf)[mfi];
269 fab.template copy<amrex::RunOn::Device>(NC_fab);
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.
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.
void Initialize()
Read in time array from file and allocate data arrays.
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.
NDArray is the datatype designed to hold any data, including scalars, multidimensional arrays,...