4#include "AMReX_ParallelDescriptor.H"
8#ifdef REMORA_USE_NETCDF
62 amrex::Print() <<
"Setting up boundary data for " <<
field_name <<
" coming from NetCDF file " << std::endl;
72 int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
82 amrex::Vector<NDArray<double>>
array_ts(1);
84 if (amrex::ParallelDescriptor::IOProcessor())
99 if (amrex::ParallelDescriptor::IOProcessor()) {
102 amrex::Error(
"Time series of boundary data must be given at at least two times");
106 if (!(amrex::ParallelDescriptor::IOProcessor())) {
153 if (
var_need_data[amrex::Orientation(amrex::Direction::x,amrex::Orientation::low)] ==
true) {
156 if (
var_need_data[amrex::Orientation(amrex::Direction::x,amrex::Orientation::high)] ==
true) {
159 if (
var_need_data[amrex::Orientation(amrex::Direction::y,amrex::Orientation::low)] ==
true) {
162 if (
var_need_data[amrex::Orientation(amrex::Direction::y,amrex::Orientation::high)] ==
true) {
177 std::string
msg =
"Boundary file " +
file_name +
" does not contain all of:";
181 msg +=
". The boundary condition requested for " +
field_name +
182 " reads from file (clamped, chapman, flather, or orlanski_rad_nudg)."
183 " Either add the missing variable(s) to the file, or give " +
field_name +
184 " a boundary condition that needs no file data, such as outflow.";
204 amrex::Arena*
Arena_Used = amrex::The_Arena();
212 for (
int nt=0; nt <
bry_times.size()-1; nt++) {
222 amrex::Abort(
"Time " + std::to_string(
time) +
" is not spanned by the boundary time"
223 +
" series for '" +
field_name +
"', which covers ["
226 +
"]. Extend the boundary file to cover the run. The file's times were"
227 +
" placed on the model clock from the reference date in their units"
228 +
" attribute (the mapping is printed when the series is loaded), so"
229 +
" also check remora.time_ref and remora.start_time.");
289 amrex::Gpu::streamSynchronize();
323 amrex::Gpu::streamSynchronize();
346 if (
var_need_data[amrex::Orientation(amrex::Direction::x,amrex::Orientation::low)] ==
true) {
353 if (
var_need_data[amrex::Orientation(amrex::Direction::x,amrex::Orientation::high)] ==
true) {
360 if (
var_need_data[amrex::Orientation(amrex::Direction::y,amrex::Orientation::low)] ==
true) {
367 if (
var_need_data[amrex::Orientation(amrex::Direction::y,amrex::Orientation::high)] ==
true) {
389 amrex::Gpu::streamSynchronize();
400 if (amrex::ParallelDescriptor::IOProcessor())
406 if (
last4 ==
"west") {
423 for (
int n(0); n <
n_plane; n++) {
428 }
else if (
last4 ==
"east") {
444 for (
int n(0); n <
n_plane; n++) {
449 }
else if (
last5 ==
"south") {
465 for (
int n(0); n <
n_plane; n++) {
470 }
else if (
last5 ==
"north") {
486 for (
int n(0); n <
n_plane; n++) {
495 amrex::ParallelDescriptor::Barrier();
500 int ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
523 amrex::Real
xfac =
one /
static_cast<amrex::Real
>(
rx);
524 amrex::Real
yfac =
one /
static_cast<amrex::Real
>(
ry);
527 if (
dat_crse.box().length(0) == 1) {
529 if (
dat_crse.box().ixType()[1] == 0) {
532 int i_f = (
i == -1) ? -1 :
rx*
i;
538 for (
int n = 1; n <
ry; n++) {
547 int i_f = (
i == -1) ? -1 :
rx*
i;
553 for (
int n = 1; n <
ry; n++) {
560 }
else if (
dat_crse.box().length(1) == 1) {
563 if (
dat_crse.box().ixType()[0] == 0) {
566 int j_f = (
j == -1) ? -1 :
ry*
j;
572 for (
int n = 1; n <
rx; n++) {
581 int j_f = (
j == -1) ? -1 :
ry*
j;
587 for (
int n = 1; n <
rx; n++) {
595 amrex::Abort(
" What am I doing here??");
constexpr amrex::Real one
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.
bool QueryNetCDFHasVars(const std::string &fname, const amrex::Vector< std::string > &var_names)
Helper function for testing whether a file carries every named variable.
double ReadNetCDFTimeOffsetDays(const std::string &fname, const std::string &time_name, double time_ref, bool units_required, bool announce)
Offset, in days, that puts a file's time variable onto the model clock.
amrex::FArrayBox yhi_dat_before
FArrayBox to store data at time_before at yhi boundary.
amrex::FArrayBox yhi_dat_after
FArrayBox to store data at time_after at yhi boundary.
amrex::GpuArray< bool, AMREX_SPACEDIM *2 > var_need_data
Array over boundaries indicating whether we need physical data for this variable.
void interp_fab(amrex::FArrayBox &dat_crse, amrex::FArrayBox &dat_fine)
spatially interpolate boundary fabs from level 0 data (read in) to current level
amrex::FArrayBox ylo_dat_before
FArrayBox to store data at time_before at ylo boundary.
amrex::FArrayBox xlo_dat_after
FArrayBox to store data at time_after at xlo boundary.
amrex::Vector< std::string > nc_var_names
Variable names that will be read from file.
amrex::FArrayBox ylo_dat_after
FArrayBox to store data at time_after at ylo boundary.
amrex::Vector< double > bry_times
Time points in netcdf file, in seconds on the model clock.
double time_before
Time in ocean_times immediately before the last time interpolated to.
void update_interpolated_to_time(double time)
Calculate interpolated values at time, in seconds on the model clock, reading in data as necessary.
void Initialize()
Read in time array from file and allocate data arrays.
amrex::FArrayBox yhi_dat_interp
FArrayBox to store data at inteprolated time at yhi boundary */.
amrex::FArrayBox xlo_dat_interp
FArrayBox to store data at inteprolated time at xlo boundary */.
std::string time_name
Field name for time series in netcdf file.
amrex::FArrayBox xhi_dat_interp
FArrayBox to store data at inteprolated time at xhi boundary */.
amrex::IntVect index_type
Index type for field to fill.
double time_after
Time in ocean_times immediately after the last time interpolated to.
int i_time_before
Time index immediately before the last time interpolated to.
std::string field_name
Field name in netcdf file.
amrex::FArrayBox ylo_dat_interp
FArrayBox to store data at inteprolated time at ylo boundary */.
NCTimeSeriesBoundary(int a_lev, const amrex::Vector< amrex::Geometry > a_geom, const amrex::Vector< std::string > &a_file_name, const std::string a_field_name, const std::string a_time_name, const amrex::IntVect a_index_type, const amrex::GpuArray< bool, AMREX_SPACEDIM *2 > &a_var_need_data, bool a_is2d, int rx, int ry, double a_time_ref)
Constructor.
amrex::Vector< amrex::Geometry > m_geom
Geometry at all levels.
amrex::FArrayBox xhi_dat_after
FArrayBox to store data at time_after at xhi boundary.
void read_in_at_time(amrex::FArrayBox &fab_xlo, amrex::FArrayBox &fab_xhi, amrex::FArrayBox &fab_ylo, amrex::FArrayBox &fab_yhi, int itime)
Read in data from file at time index itime and fill into mf.
amrex::Vector< std::string > file_names
File name to read from.
amrex::Vector< int > file_itime_offset
Offset to access a particular time within its file.
amrex::FArrayBox xhi_dat_before
FArrayBox to store data at time_before at xhi boundary.
bool is2d
Whether the field we're reading in is 2d.
int m_lev
Level at which we are holding the boundary data.
int m_rx
Refinement ratios relative to level 0.
amrex::FArrayBox xlo_dat_before
FArrayBox to store data at time_before at xlo boundary.
amrex::Vector< int > file_for_time
File index to access a particular time.
NDArray is the datatype designed to hold any data, including scalars, multidimensional arrays,...