2#include "AMReX_Interp_3D_C.H"
3#include "AMReX_PlotFileUtil.H"
9template<
typename V,
typename T>
23 const Real
dz = g.CellSizeArray()[2];
24 const Real
zlo = g.ProbLoArray()[2];
26#pragma omp parallel if (Gpu::notInLaunchRegion())
30 const Box&
bx =
mfi.tilebox();
35 const int k =
kf /
rz;
36 const int r =
kf - k *
rz;
40 if (
r > 0) {
z += (Real(
r) / Real(
rz)) * (
zp(
i,
j,k+1) -
zp(
i,
j,k)); }
53 const auto dx = g.CellSizeArray();
54 const auto plo = g.ProbLoArray();
56#pragma omp parallel if (Gpu::notInLaunchRegion())
60 const Box&
bx =
mfi.tilebox();
77 const bool nodal_z =
src.boxArray().ixType().nodeCentered(2);
79#pragma omp parallel if (Gpu::notInLaunchRegion())
83 const Box&
bx =
mfi.tilebox();
88 const int k =
kf /
rz;
90 const int r =
kf - k *
rz;
92 if (
r > 0) { v += (Real(
r) / Real(
rz)) * (
s(
i,
j,k+1) -
s(
i,
j,k)); }
105#ifndef REMORA_USE_NETCDF
133 for (
int n = 0; n <
ncons; ++n) {
140 for (
int n = 0; n <
ncons; ++n) {
200 amrex::Abort(
"Don't know this plotfile type");
217 for (
auto&
b :
bl2d) {
230#ifdef REMORA_USE_PARTICLES
322 amrex::Abort(
"Found while writing output: visc2 contains nan or inf");
325 const Box&
bx =
mfi.validbox();
326 const int K =
mfi.index();
336 for (
int n = 0; n <
ncons; ++n) {
341 const Box&
bx =
mfi.validbox();
342 const int K =
mfi.index();
353 for (
int n = 0; n <
ncons; ++n) {
364 amrex::Abort(
"Attempting to write longwave radiation flux to plotfile. Variable not allocated when bulk_fluxes turned off");
371 amrex::Abort(
"Attempting to write latent heat flux to plotfile. Variable not allocated when bulk_fluxes turned off");
378 amrex::Abort(
"Attempting to write shortwave radiation flux to plotfile. Variable not allocated when bulk_fluxes turned off");
385 amrex::Abort(
"Attempting to write sensible heat flux to plotfile. Variable not allocated when bulk_fluxes turned off");
454 amrex::Abort(
"Found while writing output: " +
cons_names[
i] +
455 " contains nan or inf");
470 amrex::Abort(
"Found while writing output: u velocity contains nan or inf");
477 amrex::Abort(
"Found while writing output: v velocity contains nan or inf");
484 amrex::Abort(
"Found while writing output: z velocity contains nan or inf");
491 Real
dx =
Geom()[
lev].CellSizeArray()[0];
492 Real
dy =
Geom()[
lev].CellSizeArray()[1];
503#pragma omp parallel if (Gpu::notInLaunchRegion())
506 const Box&
bx =
mfi.tilebox();
510 const Real
xlo =
Geom()[
lev].ProbLoArray()[0];
511 const Real
ylo =
Geom()[
lev].ProbLoArray()[1];
531#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
535 const Box&
bx =
mfi.tilebox();
540 der_function(
bx,
dfab, 0, 1,
sfab,
vec_pm[
lev]->
const_array(
mfi),
vec_pn[
lev]->
const_array(
mfi),
vec_mskr[
lev]->
const_array(
mfi),
Geom(
lev),
t_new[0],
nullptr,
lev);
543 der_function(
bx,
dfab, 0, 1,
sfab,
vec_pm[
lev]->
const_array(
mfi),
vec_pn[
lev]->
const_array(
mfi),
vec_mskr[
lev]->
const_array(
mfi),
Geom(
lev),
t_new[0],
nullptr,
lev);
562#pragma omp parallel if (Gpu::notInLaunchRegion())
565 const Box&
bx =
mfi.tilebox();
576#ifdef REMORA_USE_PARTICLES
617 amrex::Print() <<
"Writing plotfile " <<
plotfilename <<
"\n";
634#ifdef REMORA_USE_PARTICLES
642 amrex::Print() <<
"Writing plotfile " <<
plotfilename <<
"\n";
664 {
Geom()[0].isPeriodic(0),
Geom()[0].isPeriodic(1),
Geom()[0].isPeriodic(2)};
720 for (
int n = 0; n <
mf2[0].nComp(); n++) {
756#ifdef REMORA_USE_PARTICLES
775#ifdef REMORA_USE_PARTICLES
783#ifdef REMORA_USE_NETCDF
805 amrex::Abort(
"Don't know this plotfile type");
850 BL_PROFILE(
"WriteMultiLevelPlotfileWithBathymetry()");
866 "plotfile nodal set does not match the geometry written to the Header");
872 "plotfile face sets do not match the geometry written to the Header");
884 ParallelDescriptor::Barrier();
886 if (ParallelDescriptor::MyProc() == ParallelDescriptor::NProcs()-1) {
895 VisMF::IO_Buffer
io_buffer(VisMF::IO_Buffer_Size);
900 std::ofstream::trunc |
901 std::ofstream::binary);
909 if (AsyncOut::UseAsyncOut()) {
910 AsyncOut::Submit(std::move(
f));
926 if (AsyncOut::UseAsyncOut()) {
962 const MultiFab* data;
963 std::unique_ptr<MultiFab>
mf_tmp;
1184 for (
int n = 0; n < 2; ++n) {
1221 const MultiFab&
nu = *
nd[
lev];
1222 z[
lev].define(
nu.boxArray(),
nu.DistributionMap(), 1, 0);
1223 const Real
dz = g[
lev].CellSizeArray()[2];
1224 const Real
zlo = g[
lev].ProbLoArray()[2];
1225 const int klo = g[
lev].Domain().smallEnd(2);
1226 const int Nf = g[
lev].Domain().length(2);
1227 const int N =
Geom(
lev).Domain().length(2);
1234 const Box&
bx =
mfi.tilebox();
1244 const Real
eb = (k ==
klo) ? std::abs(
za(
i,
j,k) -
zp(
i,
j,0)) : Real(0.0);
1245 const Real
et = (k ==
klo +
Nf) ? std::abs(
za(
i,
j,k) -
zp(
i,
j,
N)) : Real(0.0);
1252 ParallelDescriptor::ReduceRealMax(
err_bot);
1253 ParallelDescriptor::ReduceRealMax(
err_top);
1254 amrex::Print() <<
"Plot nodal z, level " <<
lev <<
": |z_bottom - z_phys| "
1256 const Real
self_tol = Real(1.e-10) * std::max(Real(1.0), std::abs(
zlo));
1258 amrex::Abort(
"check_plot_z: the plotfile's nodal z does not reproduce z_phys_nd");
1266 r[
d] = g[
lev].Domain().length(
d) / g[
lev-1].Domain().length(
d);
1275 const Box&
bx =
mfi.tilebox();
1278 const int r0 =
r[0],
r1 =
r[1],
r2 =
r[2];
1300 const Box&
bx =
mfi.tilebox();
1306 if (
a(
i,
j,k) >=
sentinel) {
return {Real(0.0), Real(0.0), 0, 0}; }
1309 const Real
d = std::abs(
a(
i,
j,k) -
b(
i,
j,k));
1316 ParallelDescriptor::ReduceRealMax(
d_int);
1317 ParallelDescriptor::ReduceRealMax(
d_per);
1318 ParallelDescriptor::ReduceIntSum(
n_int);
1319 ParallelDescriptor::ReduceIntSum(
n_per);
1320 amrex::Print() <<
"Plot nodal z, levels " <<
lev-1 <<
"/" <<
lev
1321 <<
": coarse-fine max |dz| interior " <<
d_int <<
" (" <<
n_int <<
" nodes)"
1322 <<
", perimeter " <<
d_per <<
" (" <<
n_per <<
" nodes)\n";
1324 amrex::Abort(
"check_plot_z: coarse and fine nodal z disagree inside the patch");
1405 Gpu::streamSynchronize();
1449 const IntVect
slo =
sub.smallEnd();
1450 const IntVect
shi =
sub.bigEnd();
1458 if (
mf ==
nullptr) {
continue; }
1463#pragma omp parallel if (Gpu::notInLaunchRegion())
1471 Box
gbx =
mfi.growntilebox(IntVect(1,1,0));
1484 if (
ii !=
i ||
jj !=
j) {
1496 Gpu::streamSynchronize();
constexpr amrex::Real zero
constexpr amrex::Real myhalf
mf_h setVal(geomdata.ProbHi(2))
AMREX_ALWAYS_ASSERT(!NSPeriodic||!EWPeriodic)
pp_prob query("traditional", traditional)
bool containerHasElement(const V &iterable, const T &query)
static void fill_nodal_z_displacement(MultiFab &mf_nd, const MultiFab &z_phys_nd, const Geometry &g, int rz)
static void fill_nodal_xy_displacement(MultiFab &mf_nd, const MultiFab &mf_xy, const Geometry &g)
static void refine_in_z(const MultiFab &src, MultiFab &dst, int rz)
static PhysBCFunctNoOp null_bc_for_fill
void GetMeshPlotVar(const std::string &a_var_name, amrex::MultiFab &a_mf, const int a_lev)
void writePlotFile(const std::string &a_fname, const amrex::Vector< amrex::MultiFab > &a_xy) const
const ParticlesNamesVector & getNames() const
void GetMeshPlotVarNames(amrex::Vector< std::string > &a_names) const
static PlotfileType plotfile_type
Native or NetCDF plotfile output.
int ncons
Number of conserved scalars in the state (temperature + salt + passive scalars + biology tracers)
static bool plot_staggered_vels
Whether to write the staggered velocities (not averaged to cell centers)
amrex::Vector< amrex::BCRec > domain_bcs_type
vector (over BCVars) of BCRecs
amrex::Vector< std::string > cons_names
Names of scalars for plotfile output.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_fcor
coriolis factor (2D)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_h
multilevel data container for current step's z velocities (largely unused; W stored separately)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pm
horizontal scaling factor: 1 / dx (2D)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_lrflx
longwave radiation
void compute_omega_and_w(int lev, amrex::MultiFab *mf_omega, amrex::MultiFab *mf_wvel)
omega and w on the s_w points of the NetCDF output, ghost columns filled and masked
void WriteNCPlotFile(int istep, amrex::MultiFab const *plotMF, int lev=0, amrex::MultiFab const *mf_omega=nullptr, amrex::MultiFab const *mf_wvel=nullptr)
Write plotfile using NetCDF (wrapper)
amrex::Vector< amrex::MultiFab * > cons_new
multilevel data container for current step's scalar data: temperature, salinity, passive tracer
bool plot_omega
Whether to write omega, the S-coordinate vertical velocity, to NetCDF output.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskr
land/sea mask at cell centers (2D)
void compute_diagnostic_omega(int lev, amrex::MultiFab &mf_omega)
omega (m/s) as ROMS writes it: from mass fluxes of the current velocities
amrex::Real plotfile_fill_value
fill value for masked arrays in amrex plotfiles
void writeJobInfo(const std::string &dir) const
Write job info to stdout.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_sustr
Surface stress in the u direction.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_yp
y_grid on psi-points (2D)
amrex::Vector< amrex::MultiFab * > zvel_new
multilevel data container for current step's z velocities (largely unused; W stored separately)
int foextrap_bc() const noexcept
amrex::Vector< amrex::Vector< amrex::Box > > boxes_at_level
the boxes specified at each level by tagging criteria
amrex::Real check_plot_z_tol
abort when the coarse-fine mismatch at interior nodes exceeds this; negative (the default) only repor...
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_msku
land/sea mask at x-faces (2D)
int check_plot_z
check the nodal z a viewer rebuilds from the plotfile's Nu_nd set against z_phys_nd on each level,...
bool plot_wvel
Whether to write z_velocity, the true vertical velocity, to NetCDF output as w.
amrex::Vector< amrex::MultiFab * > yvel_new
multilevel data container for current step's y velocities (v in ROMS)
static bool plot_nodal_data
Whether to write nodal data (Nu_nd) to plotfiles.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_shflx
sensible heat flux
amrex::Vector< amrex::MultiFab * > xvel_new
multilevel data container for current step's x velocities (u in ROMS)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_lhflx
latent heat flux
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskv
land/sea mask at y-faces (2D)
amrex::Vector< int > istep
which step?
void mask_arrays_for_write(int lev, amrex::Real fill_value, amrex::Real fill_where)
Mask data arrays before writing output.
static int file_min_digits
Minimum number of digits in plotfile name or chunked history file.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_visc2_r
Harmonic viscosity defined on the rho points (centers)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_svstr
Surface stress in the v direction.
void FillBdyCCVels(int lev, amrex::MultiFab &mf_cc_vel)
Fill the physical boundary conditions for cell-centered velocity (diagnostic only)
void plot_node_coords(amrex::Vector< amrex::MultiFab > &mf_xy)
Physical (x, y) of the psi points on every level, for plotfile output.
amrex::Vector< amrex::Real > t_new
new time at each level, in seconds since start_time
static SolverChoice solverChoice
Container for algorithmic choices.
void WriteGenericPlotfileHeaderWithBathymetry(std::ostream &HeaderFile, int nlevels, const amrex::Vector< amrex::BoxArray > &bArray, const amrex::Vector< std::string > &varnames_3d, const amrex::Vector< std::string > &varnames_2d_rho, const amrex::Vector< std::string > &varnames_2d_u, const amrex::Vector< std::string > &varnames_2d_v, const amrex::Vector< amrex::Geometry > &my_geom, double time, const amrex::Vector< int > &level_steps, const amrex::Vector< amrex::IntVect > &rr, const std::string &versionName, const std::string &levelPrefix, const std::string &mfPrefix) const
write out header data for an AMReX plotfile
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_xp
x_grid on psi-points (2D)
void FillPatchNoBC(int lev, amrex::Real time, amrex::MultiFab &mf_to_be_filled, amrex::Vector< amrex::MultiFab * > const &mfs, const int bdy_var_type=BdyVars::null, const int icomp=0, const bool fill_all=true, const bool fill_set=false, amrex::Vector< amrex::MultiFab * > const &mfs_crse_old={}, amrex::Vector< amrex::MultiFab * > const &mfs_crse_new={})
Fill a new MultiFab by copying in phi from valid region and filling ghost cells without applying boun...
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_vbar
barotropic y velocity (2D)
bool expand_plotvars_to_unif_rr
whether plotfile variables should be expanded to a uniform refinement ratio
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_ubar
barotropic x velocity (2D)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_bustr
Bottom stress in the u direction.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_bvstr
Bottom stress in the v direction.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_phys_nd
z coordinates at psi points (cell nodes)
void compute_wvel(int lev, amrex::MultiFab &mf_w)
"True" vertical velocity w (m/s) at w-points, as ROMS wvelocity
amrex::Real netcdf_fill_value
fill value for masked arrays in netcdf output
void check_plot_nodal_z(const amrex::Vector< const amrex::MultiFab * > &nd, const amrex::Vector< amrex::Geometry > &g)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pn
horizontal scaling factor: 1 / dy (2D)
amrex::Vector< std::string > plot_var_names_3d
Names of 3D variables to output to AMReX plotfile.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_stflux
Surface tracer flux; input arrays.
void WriteMultiLevelPlotfileWithBathymetry(const std::string &plotfilename, int nlevels, const amrex::Vector< const amrex::MultiFab * > &mf, const amrex::Vector< const amrex::MultiFab * > &mf_nd, const amrex::Vector< const amrex::MultiFab * > &mf_u, const amrex::Vector< const amrex::MultiFab * > &mf_v, const amrex::Vector< const amrex::MultiFab * > &mf_w, const amrex::Vector< const amrex::MultiFab * > &mf_2d_rho, const amrex::Vector< const amrex::MultiFab * > &mf_2d_u, const amrex::Vector< const amrex::MultiFab * > &mf_2d_v, const amrex::Vector< std::string > &varnames_3d, const amrex::Vector< std::string > &varnames_2d_rho, const amrex::Vector< std::string > &varnames_2d_u, const amrex::Vector< std::string > &varnames_2d_v, const amrex::Vector< amrex::Geometry > &my_geom, double time, const amrex::Vector< int > &level_steps, const amrex::Vector< amrex::IntVect > &rr, const std::string &versionName="HyperCLaw-V1.1", const std::string &levelPrefix="Level_", const std::string &mfPrefix="Cell", const amrex::Vector< std::string > &extra_dirs=amrex::Vector< std::string >()) const
write out particular data to an AMReX plotfile
ParticleData particleData
Particle container with all particle species.
std::string plot_file_name
Plotfile prefix.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Zt_avg1
Average of the free surface, zeta (2D)
void WritePlotFile(int istep)
main driver for writing AMReX plotfiles
amrex::Vector< std::string > plot_var_names_2d
Names of 2D variables to output to AMReX plotfile.
double model_time(amrex::Real elapsed) const noexcept
Time on the model clock, in seconds, of an elapsed time such as t_new.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_srflx
Shortwave radiation flux [W/m²], defined at rho-points.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_diff2
Harmonic diffusivity for temperature / salinity.
static constexpr int t
cons component Temp_comp
static constexpr int null
void remora_dervort(const amrex::Box &bx, amrex::FArrayBox &derfab, int dcomp, int ncomp, const amrex::FArrayBox &datfab, const amrex::Array4< const amrex::Real > &pm, const amrex::Array4< const amrex::Real > &pn, const amrex::Array4< const amrex::Real > &, const amrex::Geometry &, amrex::Real, const int *, const int)
void remora_dernull(const amrex::Box &, amrex::FArrayBox &, int, int, const amrex::FArrayBox &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Geometry &, amrex::Real, const int *, const int)