33 Vector<Vector<FArrayBox>>& bdy_data_xlo,
34 Vector<Vector<FArrayBox>>& bdy_data_xhi,
35 Vector<Vector<FArrayBox>>& bdy_data_ylo,
36 Vector<Vector<FArrayBox>>& bdy_data_yhi,
37 int& width, Real& start_bdy_time,
38 std::string bdry_time_varname,
39 amrex::GpuArray<amrex::GpuArray<bool, AMREX_SPACEDIM*2>,
BdyVars::NumTypes+1>& phys_bc_need_data)
41 amrex::Print() <<
"Loading boundary data from NetCDF file " << nc_bdry_file << std::endl;
43 int ioproc = ParallelDescriptor::IOProcessorNumber();
45 const auto& lo = domain.loVect();
46 const auto& hi = domain.hiVect();
52 const std::string dateTimeFormat =
"%Y-%m-%d_%H:%M:%S";
54 Vector<Real> ocean_times;
58 if (ParallelDescriptor::IOProcessor())
60 if (unit_str.find(
"days") == std::string::npos) {
61 amrex::Print() <<
"Units of " << bdry_time_varname <<
" given as: " << unit_str << std::endl;
62 amrex::Abort(
"Units must be in days.");
67 amrex::Vector<RARRAY> array_ts(1);
69 if (ParallelDescriptor::IOProcessor())
71 ntimes = array_ts[0].get_vshape()[0];
72 ocean_times.resize(ntimes);
75 for (
int nt(0); nt < ntimes; nt++)
78 ocean_times[nt] = (*(array_ts[0].get_data() + nt)) * 60._rt * 60._rt * 24._rt;
82 start_bdy_time = ocean_times[0];
83 timeInterval = ocean_times[1] - ocean_times[0];
85 for (
int nt(1); nt < ntimes; nt++)
87 AMREX_ALWAYS_ASSERT(std::abs(ocean_times[nt] - ocean_times[nt-1] - timeInterval) / timeInterval <= 1e-8_rt);
91 ParallelDescriptor::Bcast(&start_bdy_time,1,ioproc);
92 ParallelDescriptor::Bcast(&ntimes,1,ioproc);
93 ParallelDescriptor::Bcast(&timeInterval,1,ioproc);
97 int nt_prior = bdy_data_xlo.size();
99 bdy_data_xlo.resize(ntimes + nt_prior);
100 bdy_data_xhi.resize(ntimes + nt_prior);
101 bdy_data_ylo.resize(ntimes + nt_prior);
102 bdy_data_yhi.resize(ntimes + nt_prior);
104 amrex::IntVect plo(lo);
105 amrex::IntVect phi(hi);
112 Vector<std::string> nc_var_names;
113 Vector<std::string> nc_var_names_full;
114 Vector<std::string> nc_var_prefix = {
"u",
"v",
"temp",
"salt",
"ubar",
"vbar",
"zeta"};
116 for (
int ip = 0; ip < nc_var_prefix.size(); ++ip)
118 if (phys_bc_need_data[ip][Orientation(Direction::x,Orientation::low)] ==
true) {
119 nc_var_names.push_back(nc_var_prefix[ip] +
"_west");
121 if (phys_bc_need_data[ip][Orientation(Direction::x,Orientation::high)] ==
true) {
122 nc_var_names.push_back(nc_var_prefix[ip] +
"_east");
124 if (phys_bc_need_data[ip][Orientation(Direction::y,Orientation::low)] ==
true) {
125 nc_var_names.push_back(nc_var_prefix[ip] +
"_south");
127 if (phys_bc_need_data[ip][Orientation(Direction::y,Orientation::high)] ==
true) {
128 nc_var_names.push_back(nc_var_prefix[ip] +
"_north");
130 nc_var_names_full.push_back(nc_var_prefix[ip] +
"_west");
131 nc_var_names_full.push_back(nc_var_prefix[ip] +
"_east");
132 nc_var_names_full.push_back(nc_var_prefix[ip] +
"_south");
133 nc_var_names_full.push_back(nc_var_prefix[ip] +
"_north");
135 int nvars_full = nc_var_names_full.size();
138 amrex::Vector<RARRAY> arrays(nc_var_names.size());
144 if (ParallelDescriptor::IOProcessor())
147 int itimes =
static_cast<int>(arrays[0].get_vshape()[0]);
148 AMREX_ALWAYS_ASSERT(itimes == ntimes);
156 ParallelDescriptor::Bcast(&width,1,ioproc);
160 for (
int iv = 0; iv < nvars_full; iv++)
166 std::string first1 = nc_var_names_full[iv].substr(0,1);
167 std::string first4 = nc_var_names_full[iv].substr(0,4);
169 if (first4 ==
"salt") {
171 }
else if (first4 ==
"ubar") {
173 }
else if (first4 ==
"vbar") {
175 }
else if (first4 ==
"zeta") {
177 }
else if (first1 ==
"u") {
179 }
else if (first1 ==
"v") {
181 }
else if (first4 ==
"temp") {
184 amrex::Print() <<
"Trying to read " << first1 <<
" or " << first4 << std::endl;
185 amrex::Abort(
"dont know this variable");
188 std::string last4 = nc_var_names_full[iv].substr(nc_var_names_full[iv].size()-4, 4);
189 std::string last5 = nc_var_names_full[iv].substr(nc_var_names_full[iv].size()-5, 5);
192 if (last4 ==
"west") {
194 }
else if (last4 ==
"east") {
196 }
else if (last5 ==
"south") {
198 }
else if (last5 ==
"north") {
202 plo[0] = lo[0]; plo[1] = lo[1]; plo[2] = lo[2];
203 phi[0] = hi[0]; phi[1] = hi[1]; phi[2] = hi[2];
204 const Box pbx(plo, phi);
206 Arena* Arena_Used = The_Arena();
208 Arena_Used = The_Pinned_Arena();
218 Box bx_for_u(IntVect(lo[0], lo[1]-1, lo[2]), IntVect(lo[0], hi[1]+1, hi[2]), IntVect(1,0,0));
221 Box bx_for_v(IntVect(lo[0]-1, lo[1], lo[2]), IntVect(lo[0]-1, hi[1]+1, hi[2]), IntVect(0,1,0));
224 Box bx_for_t(IntVect(lo[0]-1, lo[1]-1, lo[2]), IntVect(lo[0]-1, hi[1]+1, hi[2]));
228 for (
int nt(0); nt < ntimes; ++nt) {
229 bdy_data_xlo[nt + nt_prior].push_back(FArrayBox(bx_for_u, 1, Arena_Used));
232 for (
int nt(0); nt < ntimes; ++nt) {
233 bdy_data_xlo[nt + nt_prior].push_back(FArrayBox(bx_for_v , 1, Arena_Used));
236 for (
int nt(0); nt < ntimes; ++nt) {
237 bdy_data_xlo[nt + nt_prior].push_back(FArrayBox(bx_for_t, 1, Arena_Used));
240 for (
int nt(0); nt < ntimes; ++nt) {
241 bdy_data_xlo[nt + nt_prior].push_back(FArrayBox(bx_for_t, 1, Arena_Used));
244 Box xlo_ubar(makeSlab(bx_for_u,2,0));
245 for (
int nt(0); nt < ntimes; ++nt) {
246 bdy_data_xlo[nt + nt_prior].push_back(FArrayBox(xlo_ubar, 1, Arena_Used));
249 Box xlo_vbar(makeSlab(bx_for_v,2,0));
250 for (
int nt(0); nt < ntimes; ++nt) {
251 bdy_data_xlo[nt + nt_prior].push_back(FArrayBox(xlo_vbar, 1, Arena_Used));
254 Box xlo_zeta(makeSlab(bx_for_t,2,0));
255 for (
int nt(0); nt < ntimes; ++nt) {
256 bdy_data_xlo[nt + nt_prior].push_back(FArrayBox(xlo_zeta, 1, Arena_Used));
266 Box bx_for_u(IntVect(hi[0]+1, lo[1]-1, lo[2]), IntVect(hi[0]+1, hi[1]+1, hi[2]), IntVect(1,0,0));
269 Box bx_for_v(IntVect(hi[0]+1, lo[1], lo[2]), IntVect(hi[0]+1, hi[1]+1, hi[2]), IntVect(0,1,0));
272 Box bx_for_t(IntVect(hi[0]+1, lo[1]-1, lo[2]), IntVect(hi[0]+1, hi[1]+1, hi[2]));
276 for (
int nt(0); nt < ntimes; ++nt) {
277 bdy_data_xhi[nt + nt_prior].push_back(FArrayBox(bx_for_u, 1, Arena_Used));
280 for (
int nt(0); nt < ntimes; ++nt) {
281 bdy_data_xhi[nt + nt_prior].push_back(FArrayBox(bx_for_v , 1, Arena_Used));
284 for (
int nt(0); nt < ntimes; ++nt) {
285 bdy_data_xhi[nt + nt_prior].push_back(FArrayBox(bx_for_t, 1, Arena_Used));
288 for (
int nt(0); nt < ntimes; ++nt) {
289 bdy_data_xhi[nt + nt_prior].push_back(FArrayBox(bx_for_t, 1, Arena_Used));
292 Box xhi_ubar(makeSlab(bx_for_u,2,0));
293 for (
int nt(0); nt < ntimes; ++nt) {
294 bdy_data_xhi[nt + nt_prior].push_back(FArrayBox(xhi_ubar, 1, Arena_Used));
297 Box xhi_vbar(makeSlab(bx_for_v,2,0));
298 for (
int nt(0); nt < ntimes; ++nt) {
299 bdy_data_xhi[nt + nt_prior].push_back(FArrayBox(xhi_vbar, 1, Arena_Used));
302 Box xhi_zeta(makeSlab(bx_for_t,2,0));
303 for (
int nt(0); nt < ntimes; ++nt) {
304 bdy_data_xhi[nt + nt_prior].push_back(FArrayBox(xhi_zeta, 1, Arena_Used));
314 Box bx_for_v(IntVect(lo[0]-1, lo[1], lo[2]), IntVect(hi[0]+1, lo[1], hi[2]), IntVect(0,1,0));
317 Box bx_for_u(IntVect(lo[0], lo[1]-1, lo[2]), IntVect(hi[0]+1, lo[1]-1, hi[2]), IntVect(1,0,0));
320 Box bx_for_t(IntVect(lo[0]-1, lo[1]-1, lo[2]), IntVect(hi[0]+1, lo[1]-1, hi[2]));
324 for (
int nt(0); nt < ntimes; ++nt) {
325 bdy_data_ylo[nt + nt_prior].push_back(FArrayBox(bx_for_u , 1, Arena_Used));
328 for (
int nt(0); nt < ntimes; ++nt) {
329 bdy_data_ylo[nt + nt_prior].push_back(FArrayBox(bx_for_v, 1, Arena_Used));
332 for (
int nt(0); nt < ntimes; ++nt) {
333 bdy_data_ylo[nt + nt_prior].push_back(FArrayBox(bx_for_t, 1, Arena_Used));
336 for (
int nt(0); nt < ntimes; ++nt) {
337 bdy_data_ylo[nt + nt_prior].push_back(FArrayBox(bx_for_t, 1, Arena_Used));
340 Box ylo_ubar(makeSlab(bx_for_u,2,0));
341 for (
int nt(0); nt < ntimes; ++nt) {
342 bdy_data_ylo[nt + nt_prior].push_back(FArrayBox(ylo_ubar, 1, Arena_Used));
345 Box ylo_vbar(makeSlab(bx_for_v,2,0));
346 for (
int nt(0); nt < ntimes; ++nt) {
347 bdy_data_ylo[nt + nt_prior].push_back(FArrayBox(ylo_vbar, 1, Arena_Used));
350 Box ylo_zeta(makeSlab(bx_for_t,2,0));
351 for (
int nt(0); nt < ntimes; ++nt) {
352 bdy_data_ylo[nt + nt_prior].push_back(FArrayBox(ylo_zeta, 1, Arena_Used));
362 Box bx_for_v(IntVect(lo[0]-1, hi[1]+1, lo[2]), IntVect(hi[0]+1, hi[1]+1, hi[2]), IntVect(0,1,0));
365 Box bx_for_u(IntVect(lo[0], hi[1]+1, lo[2]), IntVect(hi[0]+1, hi[1]+1, hi[2]), IntVect(1,0,0));
368 Box bx_for_t(IntVect(lo[0]-1, hi[1]+1, lo[2]), IntVect(hi[0]+1, hi[1]+1, hi[2]));
372 for (
int nt(0); nt < ntimes; ++nt) {
373 bdy_data_yhi[nt + nt_prior].push_back(FArrayBox(bx_for_u , 1, Arena_Used));
376 for (
int nt(0); nt < ntimes; ++nt) {
377 bdy_data_yhi[nt + nt_prior].push_back(FArrayBox(bx_for_v, 1, Arena_Used));
380 for (
int nt(0); nt < ntimes; ++nt) {
381 bdy_data_yhi[nt + nt_prior].push_back(FArrayBox(bx_for_t, 1, Arena_Used));
384 for (
int nt(0); nt < ntimes; ++nt) {
385 bdy_data_yhi[nt + nt_prior].push_back(FArrayBox(bx_for_t, 1, Arena_Used));
388 Box yhi_ubar(makeSlab(bx_for_u,2,0));
389 for (
int nt(0); nt < ntimes; ++nt) {
390 bdy_data_yhi[nt + nt_prior].push_back(FArrayBox(yhi_ubar, 1, Arena_Used));
393 Box yhi_vbar(makeSlab(bx_for_v,2,0));
394 for (
int nt(0); nt < ntimes; ++nt) {
395 bdy_data_yhi[nt + nt_prior].push_back(FArrayBox(yhi_vbar, 1, Arena_Used));
398 Box yhi_zeta(makeSlab(bx_for_t,2,0));
399 for (
int nt(0); nt < ntimes; ++nt) {
400 bdy_data_yhi[nt + nt_prior].push_back(FArrayBox(yhi_zeta, 1, Arena_Used));
406 if (count(nc_var_names.begin(), nc_var_names.end(), nc_var_names_full[iv])) {
409 if (ParallelDescriptor::IOProcessor())
418 Array4<Real> fab_arr;
422 my_box = bdy_data_xlo[0][bdyVarType].box();
424 my_box = bdy_data_xhi[0][bdyVarType].box();
426 my_box = bdy_data_ylo[0][bdyVarType].box();
428 my_box = bdy_data_yhi[0][bdyVarType].box();
434 if (my_box.length()[2] == 1) {
436 ny = arrays[iv_read].get_vshape()[1];
438 nz = arrays[iv_read].get_vshape()[1];
439 ny = arrays[iv_read].get_vshape()[2];
443 AMREX_ALWAYS_ASSERT(my_box.numPts() == n_plane);
445 int i = my_box.smallEnd()[0];
446 int joff = my_box.smallEnd()[1];
448 for (
int nt(0); nt < ntimes; ++nt)
451 fab_arr = bdy_data_xlo[nt + nt_prior][bdyVarType].array();
453 fab_arr = bdy_data_xhi[nt + nt_prior][bdyVarType].array();
455 int n_off = nt * n_plane;
457 for (
int n(0); n < n_plane; ++n) {
459 int j = n - (k * ny);
460 fab_arr(i, j+joff, k, 0) =
static_cast<Real
>(*(arrays[iv_read].get_data() + n + n_off));
466 if (my_box.length()[2] == 1) {
468 nx = arrays[iv_read].get_vshape()[1];
470 nz = arrays[iv_read].get_vshape()[1];
471 nx = arrays[iv_read].get_vshape()[2];
475 AMREX_ALWAYS_ASSERT(my_box.numPts() == n_plane);
477 int j = my_box.smallEnd()[1];
478 int ioff = my_box.smallEnd()[0];
480 for (
int nt(0); nt < ntimes; ++nt)
483 fab_arr = bdy_data_ylo[nt + nt_prior][bdyVarType].array();
485 fab_arr = bdy_data_yhi[nt + nt_prior][bdyVarType].array();
487 int n_off = nt * n_plane;
489 for (
int n(0); n < n_plane; ++n) {
491 int i = n - (k * nx);
493 fab_arr(i+ioff, j, k, 0) =
static_cast<Real
>(*(arrays[iv_read].get_data() + n + n_off));
504 amrex::ParallelDescriptor::Barrier();
509 for (
int nt = nt_prior; nt < bdy_data_xlo.size(); nt++)
511 for (
int i = 0; i < bdy_data_xlo[nt].size(); i++)
513 ParallelDescriptor::Bcast(bdy_data_xlo[nt][i].dataPtr(),bdy_data_xlo[nt][i].box().numPts(),ioproc);
516 for (
int nt = nt_prior; nt < bdy_data_ylo.size(); nt++)
518 for (
int i = 0; i < bdy_data_ylo[nt].size(); i++)
520 ParallelDescriptor::Bcast(bdy_data_ylo[nt][i].dataPtr(),bdy_data_ylo[nt][i].box().numPts(),ioproc);
523 for (
int nt = nt_prior; nt < bdy_data_xhi.size(); nt++)
525 for (
int i = 0; i < bdy_data_xhi[nt].size(); i++)
527 ParallelDescriptor::Bcast(bdy_data_xhi[nt][i].dataPtr(),bdy_data_xhi[nt][i].box().numPts(),ioproc);
530 for (
int nt = nt_prior; nt < bdy_data_yhi.size(); nt++)
532 for (
int i = 0; i < bdy_data_yhi[nt].size(); i++)
534 ParallelDescriptor::Bcast(bdy_data_yhi[nt][i].dataPtr(),bdy_data_yhi[nt][i].box().numPts(),ioproc);
539 ParallelDescriptor::Bcast(&timeInterval,1,ioproc);
541 int total_times = nt_prior + ntimes;
543 ParallelDescriptor::Bcast(&total_times,1,ioproc);