REMORA
Energy Research and Forecasting: An Atmospheric Modeling Code
REMORA Class Reference

#include <REMORA.H>

Inheritance diagram for REMORA:
Collaboration diagram for REMORA:

Public Member Functions

 REMORA ()
 
virtual ~REMORA ()
 
void Evolve ()
 
virtual void ErrorEst (int lev, amrex::TagBoxArray &tags, amrex::Real time, int ngrow) override
 
void InitData ()
 
void init_only (int lev, amrex::Real time)
 
void restart ()
 
void post_timestep (int nstep, amrex::Real time, amrex::Real dt_lev)
 
void sum_integrated_quantities (amrex::Real time)
 
amrex::Real volWgtSumMF (int lev, const amrex::MultiFab &mf, int comp, bool local, bool finemask)
 
bool is_it_time_for_action (int nstep, amrex::Real time, amrex::Real dt, int action_interval, amrex::Real action_per)
 
virtual void MakeNewLevelFromCoarse (int lev, amrex::Real time, const amrex::BoxArray &ba, const amrex::DistributionMapping &dm) override
 
virtual void RemakeLevel (int lev, amrex::Real time, const amrex::BoxArray &ba, const amrex::DistributionMapping &dm) override
 
virtual void ClearLevel (int lev) override
 
virtual void MakeNewLevelFromScratch (int lev, amrex::Real time, const amrex::BoxArray &ba, const amrex::DistributionMapping &dm) override
 
amrex::Real estTimeStep (int lev) const
 
void remora_advance (int level, amrex::MultiFab &cons_old, amrex::MultiFab &cons_new, amrex::MultiFab &xvel_old, amrex::MultiFab &yvel_old, amrex::MultiFab &zvel_old, amrex::MultiFab &xvel_new, amrex::MultiFab &yvel_new, amrex::MultiFab &zvel_new, amrex::MultiFab &source, const amrex::Geometry fine_geom, const amrex::Real dt, const amrex::Real time)
 
amrex::MultiFab & build_fine_mask (int lev)
 
void WritePlotFile (int which, amrex::Vector< std::string > plot_var_names)
 
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< std::string > &varnames, amrex::Real time, const amrex::Vector< int > &level_steps, 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
 
void WriteGenericPlotfileHeaderWithBathymetry (std::ostream &HeaderFile, int nlevels, const amrex::Vector< amrex::BoxArray > &bArray, const amrex::Vector< std::string > &varnames, amrex::Real time, const amrex::Vector< int > &level_steps, const std::string &versionName, const std::string &levelPrefix, const std::string &mfPrefix) const
 
void Advance (int lev, amrex::Real time, amrex::Real dt_lev, int iteration, int ncycle)
 
void setup_step (int lev, amrex::Real time, amrex::Real dt_lev)
 
void advance_3d_ml (int lev, amrex::Real dt_lev)
 
void advance_2d_onestep (int lev, amrex::Real dt_lev, amrex::Real dtfast_lev, int my_iif, int nfast_counter)
 
void advance_2d (int lev, amrex::MultiFab const *mf_rhoS, amrex::MultiFab const *mf_rhoA, amrex::MultiFab *mf_ru, amrex::MultiFab *mf_rv, amrex::MultiFab *mf_rufrc, amrex::MultiFab *mf_rvfrc, amrex::MultiFab *mf_Zt_avg1, std::unique_ptr< amrex::MultiFab > &mf_DU_avg1, std::unique_ptr< amrex::MultiFab > &mf_DU_avg2, std::unique_ptr< amrex::MultiFab > &mf_DV_avg1, std::unique_ptr< amrex::MultiFab > &mf_DV_avg2, std::unique_ptr< amrex::MultiFab > &mf_rubar, std::unique_ptr< amrex::MultiFab > &mf_rvbar, std::unique_ptr< amrex::MultiFab > &mf_rzeta, std::unique_ptr< amrex::MultiFab > &mf_ubar, std::unique_ptr< amrex::MultiFab > &mf_vbar, amrex::MultiFab *mf_zeta, amrex::MultiFab const *mf_h, amrex::MultiFab const *mf_pm, amrex::MultiFab const *mf_pn, amrex::MultiFab const *mf_fcor, amrex::MultiFab const *mf_visc2_p, amrex::MultiFab const *mf_visc2_r, const amrex::Real dtfast_lev, const bool predictor_2d_step, const bool first_2d_step, int my_iif, int &next_indx1)
 
void advance_3d (int lev, amrex::MultiFab &mf_cons, amrex::MultiFab &mf_u, amrex::MultiFab &mf_v, amrex::MultiFab *mf_sstore, amrex::MultiFab *mf_ru, amrex::MultiFab *mf_rv, std::unique_ptr< amrex::MultiFab > &mf_DU_avg1, std::unique_ptr< amrex::MultiFab > &mf_DU_avg2, std::unique_ptr< amrex::MultiFab > &mf_DV_avg1, std::unique_ptr< amrex::MultiFab > &mf_DV_avg2, std::unique_ptr< amrex::MultiFab > &mf_ubar, std::unique_ptr< amrex::MultiFab > &mf_vbar, std::unique_ptr< amrex::MultiFab > &mf_Akv, std::unique_ptr< amrex::MultiFab > &mf_Akt, std::unique_ptr< amrex::MultiFab > &mf_Hz, std::unique_ptr< amrex::MultiFab > &mf_Huon, std::unique_ptr< amrex::MultiFab > &mf_Hvom, std::unique_ptr< amrex::MultiFab > &mf_z_w, amrex::MultiFab const *mf_h, amrex::MultiFab const *mf_pm, amrex::MultiFab const *mf_pn, const int N, const amrex::Real dt_lev)
 
void prestep (int lev, amrex::MultiFab &mf_uold, amrex::MultiFab &mf_vold, amrex::MultiFab &mf_u, amrex::MultiFab &mf_v, amrex::MultiFab *mf_ru, amrex::MultiFab *mf_rv, amrex::MultiFab &S_old, amrex::MultiFab &S_new, amrex::MultiFab &mf_W, amrex::MultiFab &mf_DC, const amrex::MultiFab *mf_z_r, const amrex::MultiFab *mf_z_w, const amrex::MultiFab *mf_h, const amrex::MultiFab *mf_pm, const amrex::MultiFab *mf_pn, const amrex::MultiFab *mf_sustr, const amrex::MultiFab *mf_svstr, const amrex::MultiFab *mf_bustr, const amrex::MultiFab *mf_bvstr, const int iic, const int nfirst, const int nnew, int nstp, int nrhs, int N, const amrex::Real dt_lev)
 
void prestep_t_advection (const amrex::Box &tbx, const amrex::Box &gbx, const amrex::Array4< amrex::Real > &tempold, const amrex::Array4< amrex::Real > &tempcache, const amrex::Array4< amrex::Real > &Hz, const amrex::Array4< amrex::Real > &Huon, const amrex::Array4< amrex::Real > &Hvom, const amrex::Array4< amrex::Real > &W, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real > &sstore, const amrex::Array4< amrex::Real const > &z_w, const amrex::Array4< amrex::Real const > &h, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, int iic, int ntfirst, int nrhs, int N, const amrex::Real dt_lev)
 
void rhs_t_3d (const amrex::Box &bx, const amrex::Box &gbx, const amrex::Array4< amrex::Real > &t, const amrex::Array4< amrex::Real const > &tempstore, const amrex::Array4< amrex::Real const > &Huon, const amrex::Array4< amrex::Real const > &Hvom, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pn, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &W, const amrex::Array4< amrex::Real > &FC, int nrhs, int nnew, int N, const amrex::Real dt_lev)
 
void rhs_uv_3d (const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real > &rufrc, const amrex::Array4< amrex::Real > &rvfrc, const amrex::Array4< amrex::Real const > &sustr, const amrex::Array4< amrex::Real const > &svstr, const amrex::Array4< amrex::Real const > &bustr, const amrex::Array4< amrex::Real const > &bvstr, const amrex::Array4< amrex::Real const > &Huon, const amrex::Array4< amrex::Real const > &Hvom, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, const amrex::Array4< amrex::Real const > &W, const amrex::Array4< amrex::Real > &FC, int nrhs, int N)
 
void rhs_uv_2d (const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real const > &Duon, const amrex::Array4< amrex::Real const > &Dvom, const int nrhs)
 
void rho_eos (const amrex::Box &bx, const amrex::Array4< amrex::Real const > &state, const amrex::Array4< amrex::Real > &rho, const amrex::Array4< amrex::Real > &rhoA, const amrex::Array4< amrex::Real > &rhoS, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &z_w, const amrex::Array4< amrex::Real const > &h, const int N)
 
void prsgrd (const amrex::Box &bx, const amrex::Box &gbx, const amrex::Box &utbx, const amrex::Box &vtbx, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real const > &pn, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &rho, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &z_r, const amrex::Array4< amrex::Real const > &z_w, const int nrhs, const int N)
 
void prestep_diffusion (const amrex::Box &bx, const amrex::Box &gbx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &vel, const amrex::Array4< amrex::Real const > &vel_old, const amrex::Array4< amrex::Real > &rvel, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &Akv, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real const > &sstr, const amrex::Array4< amrex::Real const > &bstr, const amrex::Array4< amrex::Real const > &z_r, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, const int iic, const int ntfirst, const int nnew, int nstp, int nrhs, int N, const amrex::Real lambda, const amrex::Real dt_lev)
 
void vert_visc_3d (const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real > &Hzk, const amrex::Array4< amrex::Real > &AK, const amrex::Array4< amrex::Real > &Akv, const amrex::Array4< amrex::Real > &BC, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real > &CF, const int nnew, const int N, const amrex::Real dt_lev)
 
void update_massflux_3d (const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real > &phibar, const amrex::Array4< amrex::Real > &Hphi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pm_or_pn, const amrex::Array4< amrex::Real const > &Dphi1, const amrex::Array4< amrex::Real const > &Dphi2, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const int nnew)
 
void vert_mean_3d (const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &Dphi_avg1, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &CF, const amrex::Array4< amrex::Real const > &dxlen, const int nnew, const int N)
 
void uv3dmix (const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real > &u, const amrex::Array4< amrex::Real > &v, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &rufrc, const amrex::Array4< amrex::Real > &rvfrc, const amrex::Array4< amrex::Real const > &visc2_p, const amrex::Array4< amrex::Real const > &visc2_r, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, int nrhs, int nnew, const amrex::Real dt_lev)
 
void t3dmix (const amrex::Box &bx, const amrex::Array4< amrex::Real > &state, const amrex::Array4< amrex::Real const > &diff2, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, const amrex::Real dt_lev, const int ncomp)
 
void coriolis (const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &fomn, int nrhs, int nr)
 
void set_2darrays (int lev)
 
void set_bathymetry (int lev)
 
void set_coriolis (int lev)
 
void stretch_transform (int lev)
 
void set_vmix (int lev)
 
void set_smflux (int lev, amrex::Real time)
 
void set_hmixcoef (int lev)
 
void set_drag (int lev)
 
void set_weights (int lev)
 
void FillPatch (int lev, amrex::Real time, amrex::MultiFab &mf_to_be_filled, amrex::Vector< amrex::MultiFab * > const &mfs, const int bdy_var_type=BdyVars::null)
 
void fill_from_bdyfiles (amrex::MultiFab &mf_to_fill, const amrex::Real time, const int bdy_var_type)
 
void init_beta_plane_coriolis (int lev)
 
void writeJobInfo (const std::string &dir) const
 

Static Public Member Functions

static void writeBuildInfo (std::ostream &os)
 

Public Attributes

std::string pp_prefix {"remora"}
 
amrex::Vector< amrex::MultiFab * > cons_old
 
amrex::Vector< amrex::MultiFab * > xvel_old
 
amrex::Vector< amrex::MultiFab * > yvel_old
 
amrex::Vector< amrex::MultiFab * > zvel_old
 
amrex::Vector< amrex::MultiFab * > cons_new
 
amrex::Vector< amrex::MultiFab * > xvel_new
 
amrex::Vector< amrex::MultiFab * > yvel_new
 
amrex::Vector< amrex::MultiFab * > zvel_new
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_hOfTheConfusingName
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Hz
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Huon
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Hvom
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_ru
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rv
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rufrc
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rvfrc
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Akv
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Akt
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_visc2_p
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_visc2_r
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_diff2
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_x_r
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_y_r
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_r
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_w
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_s_r
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_phys_nd
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Zt_avg1
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_sustr
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_svstr
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rdrag
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_bustr
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_bvstr
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_DU_avg1
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_DU_avg2
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_DV_avg1
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_DV_avg2
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rubar
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rvbar
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rzeta
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_ubar
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_vbar
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_zeta
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pm
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pn
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_fcor
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_sstore
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_visc3d_r
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rhoS
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rhoA
 
amrex::Vector< amrex::Real > vec_weight1
 
amrex::Vector< amrex::Real > vec_weight2
 

Private Member Functions

void ReadParameters ()
 
void AverageDown ()
 
void init1DArrays ()
 
void init_bcs ()
 
void init_custom (int lev)
 
void init_stuff (int lev, const amrex::BoxArray &ba, const amrex::DistributionMapping &dm)
 
void resize_stuff (int lev)
 
void AverageDownTo (int crse_lev)
 
void FillCoarsePatch (int lev, amrex::Real time, amrex::MultiFab *mf_fine, amrex::MultiFab *mf_crse)
 
TimeInterpolatedData GetDataAtTime (int lev, amrex::Real time)
 
void timeStep (int lev, amrex::Real time, int iteration)
 
void timeStepML (amrex::Real time, int iteration)
 
void initHSE ()
 Initialize HSE. More...
 
void initRayleigh ()
 Initialize Rayleigh damping profiles. More...
 
void ComputeDt ()
 
std::string PlotFileName (int lev) const
 
amrex::Vector< std::string > PlotFileVarNames (amrex::Vector< std::string > plot_var_names) const
 
void setPlotVariables (const std::string &pp_plot_var_names, amrex::Vector< std::string > &plot_var_names)
 
void WriteCheckpointFile () const
 
void ReadCheckpointFile ()
 
void InitializeFromFile ()
 
void InitializeLevelFromData (int lev, const amrex::MultiFab &initial_data)
 
void post_update (amrex::MultiFab &state_mf, const amrex::Real time, const amrex::Geometry &geom)
 
void fill_rhs (amrex::MultiFab &rhs_mf, const amrex::MultiFab &state_mf, const amrex::Real time, const amrex::Geometry &geom)
 
void refinement_criteria_setup ()
 
AMREX_FORCE_INLINE int ComputeGhostCells (const int &spatial_order)
 
AMREX_FORCE_INLINE amrex::YAFluxRegister * getAdvFluxReg (int lev)
 
AMREX_FORCE_INLINE std::ostream & DataLog (int i)
 
AMREX_FORCE_INLINE int NumDataLogs () noexcept
 
amrex::Real getCPUTime () const
 
void setRecordDataInfo (int i, const std::string &filename)
 
const std::string DataLogName (int i) const noexcept
 The filename of the ith datalog file. More...
 

Static Private Member Functions

static void GotoNextLine (std::istream &is)
 

Private Attributes

amrex::Vector< int > num_boxes_at_level
 
amrex::Vector< int > num_files_at_level
 
amrex::Vector< amrex::Vector< amrex::Box > > boxes_at_level
 
amrex::Vector< int > istep
 
amrex::Vector< int > nsubsteps
 
amrex::Vector< amrex::Real > t_new
 
amrex::Vector< amrex::Real > t_old
 
amrex::Vector< amrex::Real > dt
 
amrex::Vector< std::unique_ptr< REMORAPhysBCFunct > > physbcs
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > mapfac_m
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > mapfac_u
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > mapfac_v
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > sst
 
amrex::Vector< amrex::YAFluxRegister * > advflux_reg
 
amrex::Vector< amrex::BCRec > domain_bcs_type
 
amrex::Gpu::DeviceVector< amrex::BCRec > domain_bcs_type_d
 
amrex::Array< std::string, 2 *AMREX_SPACEDIM > domain_bc_type
 
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NCONSm_bc_extdir_vals
 
amrex::GpuArray< REMORA_BC, AMREX_SPACEDIM *2 > phys_bc_type
 
int last_plot_file_step_1
 
int last_plot_file_step_2
 
int last_check_file_step
 
int plot_file_on_restart = 1
 
int max_step = std::numeric_limits<int>::max()
 
amrex::Real stop_time = std::numeric_limits<amrex::Real>::max()
 
std::string restart_chkfile = ""
 
int nfast
 
int do_substep
 
int regrid_int = 2
 
std::string plot_file_1 {"plt_1_"}
 
std::string plot_file_2 {"plt_2_"}
 
int plot_int_1 = -1
 
int plot_int_2 = -1
 
std::string check_file {"chk"}
 
int check_int = -1
 
amrex::Vector< std::string > plot_var_names_1
 
amrex::Vector< std::string > plot_var_names_2
 
const amrex::Vector< std::string > cons_names {"temp", "salt", "scalar"}
 
const amrex::Vector< std::string > derived_names {"dpdx", "dpdy"}
 
amrex::Vector< amrex::Real > h_havg_density
 
amrex::Vector< amrex::Real > h_havg_temperature
 
amrex::Vector< amrex::Real > h_havg_pressure
 
amrex::Gpu::DeviceVector< amrex::Real > d_havg_density
 
amrex::Gpu::DeviceVector< amrex::Real > d_havg_temperature
 
amrex::Gpu::DeviceVector< amrex::Real > d_havg_pressure
 
amrex::MultiFab fine_mask
 
amrex::Vector< std::unique_ptr< std::fstream > > datalog
 
amrex::Vector< std::string > datalogname
 

Static Private Attributes

static amrex::Real cfl = 0.8
 
static amrex::Real init_shrink = 1.0
 
static amrex::Real change_max = 1.1
 
static amrex::Real fixed_dt = -1.0
 
static amrex::Real fixed_fast_dt = -1.0
 
static int fixed_ndtfast_ratio = 0
 
static SolverChoice solverChoice
 
static int verbose = 0
 
static bool use_tracer_particles
 
static int sum_interval = -1
 
static amrex::Real sum_per = -1.0
 
static PlotfileType plotfile_type = PlotfileType::amrex
 
static amrex::Vector< amrex::Vector< std::string > > nc_init_file
 
static amrex::Vector< amrex::Vector< std::string > > nc_grid_file
 
static std::string nc_bdry_file
 
static std::string input_sounding_file
 
static int output_1d_column
 
static int column_interval
 
static amrex::Real column_per
 
static amrex::Real column_loc_x
 
static amrex::Real column_loc_y
 
static std::string column_file_name
 
static int output_bndry_planes
 
static int bndry_output_planes_interval
 
static amrex::Real bndry_output_planes_per
 
static amrex::Real bndry_output_planes_start_time
 
static int input_bndry_planes
 
static amrex::Vector< amrex::AMRErrorTag > ref_tags
 
static amrex::Real startCPUTime = 0.0
 
static amrex::Real previousCPUTimeUsed = 0.0
 

Constructor & Destructor Documentation

◆ REMORA()

REMORA::REMORA ( )

constructor - reads in parameters from inputs file

  • sizes multilevel arrays and data structures
62 {
63  if (ParallelDescriptor::IOProcessor()) {
64  const char* remora_hash = amrex::buildInfoGetGitHash(1);
65  const char* amrex_hash = amrex::buildInfoGetGitHash(2);
66  const char* buildgithash = amrex::buildInfoGetBuildGitHash();
67  const char* buildgitname = amrex::buildInfoGetBuildGitName();
68 
69  if (strlen(remora_hash) > 0) {
70  amrex::Print() << "\n"
71  << "REMORA git hash: " << remora_hash << "\n";
72  }
73  if (strlen(amrex_hash) > 0) {
74  amrex::Print() << "AMReX git hash: " << amrex_hash << "\n";
75  }
76  if (strlen(buildgithash) > 0) {
77  amrex::Print() << buildgitname << " git hash: " << buildgithash << "\n";
78  }
79 
80  amrex::Print() << "\n";
81  }
82 
84  const std::string& pv1 = "plot_vars_1"; setPlotVariables(pv1,plot_var_names_1);
85  const std::string& pv2 = "plot_vars_2"; setPlotVariables(pv2,plot_var_names_2);
86 
87  amrex_probinit(geom[0].ProbLo(),geom[0].ProbHi());
88 
89  // Geometry on all levels has been defined already.
90 
91  // No valid BoxArray and DistributionMapping have been defined.
92  // But the arrays for them have been resized.
93 
94  int nlevs_max = max_level + 1;
95 
96  istep.resize(nlevs_max, 0);
97  nsubsteps.resize(nlevs_max, 1);
98  for (int lev = 1; lev <= max_level; ++lev) {
99  nsubsteps[lev] = do_substep ? MaxRefRatio(lev-1) : 1;
100  }
101 
102  physbcs.resize(nlevs_max);
103 
104  t_new.resize(nlevs_max, 0.0);
105  t_old.resize(nlevs_max, -1.e100);
106  dt.resize(nlevs_max, 1.e100);
107 
108  cons_new.resize(nlevs_max);
109  cons_old.resize(nlevs_max);
110  xvel_new.resize(nlevs_max);
111  xvel_old.resize(nlevs_max);
112  yvel_new.resize(nlevs_max);
113  yvel_old.resize(nlevs_max);
114  zvel_new.resize(nlevs_max);
115  zvel_old.resize(nlevs_max);
116 
117  advflux_reg.resize(nlevs_max);
118 
119  // Initialize tagging criteria for mesh refinement
121 
122  // We have already read in the ref_Ratio (via amr.ref_ratio =) but we need to enforce
123  // that there is no refinement in the vertical so we test on that here.
124  for (int lev = 0; lev < max_level; ++lev)
125  {
126  amrex::Print() << "Refinement ratio at level " << lev << " set to be " <<
127  ref_ratio[lev][0] << " " << ref_ratio[lev][1] << " " << ref_ratio[lev][2] << std::endl;
128 
129  if (ref_ratio[lev][2] != 1)
130  {
131  amrex::Error("We don't allow refinement in the vertical -- make sure to set ref_ratio = 1 in z");
132  }
133  }
134 }
amrex::Vector< std::string > plot_var_names_1
Definition: REMORA.H:809
amrex::Vector< amrex::MultiFab * > cons_new
Definition: REMORA.H:188
int do_substep
Definition: REMORA.H:793
amrex::Vector< std::string > plot_var_names_2
Definition: REMORA.H:810
amrex::Vector< amrex::MultiFab * > zvel_new
Definition: REMORA.H:191
amrex::Vector< amrex::MultiFab * > xvel_old
Definition: REMORA.H:184
amrex::Vector< amrex::MultiFab * > yvel_new
Definition: REMORA.H:190
amrex::Vector< amrex::MultiFab * > zvel_old
Definition: REMORA.H:186
amrex::Vector< amrex::MultiFab * > xvel_new
Definition: REMORA.H:189
void refinement_criteria_setup()
Definition: REMORA_Tagging.cpp:39
amrex::Vector< int > nsubsteps
Definition: REMORA.H:730
amrex::Vector< std::unique_ptr< REMORAPhysBCFunct > > physbcs
Definition: REMORA.H:737
amrex::Vector< int > istep
Definition: REMORA.H:729
amrex::Vector< amrex::MultiFab * > yvel_old
Definition: REMORA.H:185
amrex::Vector< amrex::YAFluxRegister * > advflux_reg
Definition: REMORA.H:748
amrex::Vector< amrex::Real > t_new
Definition: REMORA.H:733
void ReadParameters()
Definition: REMORA.cpp:484
amrex::Vector< amrex::MultiFab * > cons_old
Definition: REMORA.H:183
amrex::Vector< amrex::Real > t_old
Definition: REMORA.H:734
amrex::Vector< amrex::Real > dt
Definition: REMORA.H:735
void setPlotVariables(const std::string &pp_plot_var_names, amrex::Vector< std::string > &plot_var_names)
Definition: Plotfile.cpp:9
void amrex_probinit(const amrex_real *problo, const amrex_real *probhi)
Here is the call graph for this function:

◆ ~REMORA()

REMORA::~REMORA ( )
virtual
137 {
138 }

Member Function Documentation

◆ Advance()

void REMORA::Advance ( int  lev,
amrex::Real  time,
amrex::Real  dt_lev,
int  iteration,
int  ncycle 
)

advance a single level for a single time step

8 {
9  BL_PROFILE("REMORA::Advance()");
10 
11  setup_step(lev, time, dt_lev);
12 
14  {
15  int nfast_counter=nfast + 1;
16 
17  //***************************************************
18  //Compute fast timestep from dt_lev and ratio
19  //***************************************************
20  Real dtfast_lev=dt_lev/Real(fixed_ndtfast_ratio);
21 
22  //***************************************************
23  //Advance nfast_counter steps of the 2d integrator
24  //***************************************************
25  for (int my_iif = 0; my_iif < nfast_counter; my_iif++) {
26  advance_2d_onestep(lev, dt_lev, dtfast_lev, my_iif, nfast_counter);
27  }
28  }
29 
30  //***************************************************
31  //Advance one step of the 3d integrator
32  //***************************************************
33  advance_3d_ml(lev, dt_lev);
34 }
int nfast
Definition: REMORA.H:790
void advance_2d_onestep(int lev, amrex::Real dt_lev, amrex::Real dtfast_lev, int my_iif, int nfast_counter)
Definition: REMORA_advance_2d_onestep.cpp:6
void advance_3d_ml(int lev, amrex::Real dt_lev)
Definition: REMORA_advance_3d_ml.cpp:6
static SolverChoice solverChoice
Definition: REMORA.H:822
static int fixed_ndtfast_ratio
Definition: REMORA.H:789
void setup_step(int lev, amrex::Real time, amrex::Real dt_lev)
Definition: REMORA_setup_step.cpp:7
bool use_barotropic
Definition: DataStruct.H:200

◆ advance_2d()

void REMORA::advance_2d ( int  lev,
amrex::MultiFab const *  mf_rhoS,
amrex::MultiFab const *  mf_rhoA,
amrex::MultiFab *  mf_ru,
amrex::MultiFab *  mf_rv,
amrex::MultiFab *  mf_rufrc,
amrex::MultiFab *  mf_rvfrc,
amrex::MultiFab *  mf_Zt_avg1,
std::unique_ptr< amrex::MultiFab > &  mf_DU_avg1,
std::unique_ptr< amrex::MultiFab > &  mf_DU_avg2,
std::unique_ptr< amrex::MultiFab > &  mf_DV_avg1,
std::unique_ptr< amrex::MultiFab > &  mf_DV_avg2,
std::unique_ptr< amrex::MultiFab > &  mf_rubar,
std::unique_ptr< amrex::MultiFab > &  mf_rvbar,
std::unique_ptr< amrex::MultiFab > &  mf_rzeta,
std::unique_ptr< amrex::MultiFab > &  mf_ubar,
std::unique_ptr< amrex::MultiFab > &  mf_vbar,
amrex::MultiFab *  mf_zeta,
amrex::MultiFab const *  mf_h,
amrex::MultiFab const *  mf_pm,
amrex::MultiFab const *  mf_pn,
amrex::MultiFab const *  mf_fcor,
amrex::MultiFab const *  mf_visc2_p,
amrex::MultiFab const *  mf_visc2_r,
const amrex::Real  dtfast_lev,
const bool  predictor_2d_step,
const bool  first_2d_step,
int  my_iif,
int &  next_indx1 
)

Perform a 2D predictor (predictor_2d_step=True) or corrector (predictor_2d_step=False) step

Function that coordinates the evolution across levels – this calls Advance to do the actual advance at this level, then recursively calls itself at finer levels

Parameters
[in]levlevel of refinement (coarsest level is 0)
[in]mf_rhoS
[in]mf_rhoA
[in]mf_ru
[in]mf_rv
[in,out]mf_rufrc
[in,out]mf_rvfrc
[in,out]mf_Zt_avg1
[in,out]mf_DU_avg1
[in,out]mf_DU_avg2
[in,out]mf_DV_avg1
[in,out]mf_DV_avg2
[in,out]mf_rubar
[in,out]mf_rvbar
[in,out]mf_zeta
[in]mf_h
[in,out]mf_visc2_p
[in,out]mf_visc2_f
[in]dtfast_lev
[in]predictor_2d_step
[in]first_2d_step
[in]my_iif
[in]next_indx1
65 {
66  int iic = istep[lev];
67  const int nnew = 0;
68  const int nstp = 0;
69  int ntfirst = 0;
70 
71  int knew = 3;
72  int krhs = (my_iif + iic) % 2 + 1;
73  int kstp = my_iif <=1 ? iic % 2 + 1 : (iic % 2 + my_iif % 2 + 1) % 2 + 1;
74  int indx1 = krhs;
75  if (predictor_2d_step) {
76  next_indx1 = 3 - indx1;
77  } else {
78  knew = next_indx1;
79  kstp = 3 - knew;
80  krhs = 3;
81  //If it's not the auxiliary time step, set indx1 to next_indx1
82  // NOTE: should this ever not execute?
83  if (my_iif<nfast+1)
84  indx1=next_indx1;
85  }
86  int ptsk = 3-kstp;
87  knew-=1;
88  krhs-=1;
89  kstp-=1;
90  indx1-=1;
91  ptsk-=1;
92  auto ba = mf_h->boxArray();
93  auto dm = mf_h->DistributionMap();
94 
95  MultiFab mf_DUon(convert(ba,IntVect(1,0,0)),dm,1,IntVect(NGROW,NGROW,0));
96  MultiFab mf_DVom(convert(ba,IntVect(0,1,0)),dm,1,IntVect(NGROW,NGROW,0));
97 
98  for ( MFIter mfi(*mf_rhoS, TilingIfNotGPU()); mfi.isValid(); ++mfi )
99  {
100  Array4<Real > const& ubar = mf_ubar->array(mfi);
101  Array4<Real > const& vbar = mf_vbar->array(mfi);
102  Array4<Real > const& zeta = mf_zeta->array(mfi);
103  Array4<Real const> const& h = mf_h->const_array(mfi);
104 
105  Array4<Real const> const& pm = mf_pm->const_array(mfi);
106  Array4<Real const> const& pn = mf_pn->const_array(mfi);
107 
108  Box bx = mfi.tilebox();
109  Box gbx = mfi.growntilebox();
110  Box gbx1 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
111  Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
112  Box xgbx2 = mfi.grownnodaltilebox(0, IntVect(NGROW,NGROW,0));
113  Box ygbx2 = mfi.grownnodaltilebox(1, IntVect(NGROW,NGROW,0));
114 
115  Box tbxp1 = bx;
116  Box tbxp11 = bx;
117  Box tbxp2 = bx;
118  Box tbxp3 = bx;
119  tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
120  tbxp2.grow(IntVect(NGROW,NGROW,0));
121  tbxp11.grow(IntVect(NGROW-1,NGROW-1,NGROW-1));
122  tbxp3.grow(IntVect(NGROW+1,NGROW+1,0));
123 
124  Box bxD = bx ; bxD.makeSlab(2,0);
125  Box gbxD = gbx ; gbxD.makeSlab(2,0);
126  Box gbx1D = gbx1; gbx1D.makeSlab(2,0);
127  Box gbx2D = gbx2; gbx2D.makeSlab(2,0);
128 
129  Box tbxp2D = tbxp2;
130  tbxp2D.makeSlab(2,0);
131 
132  // step2d work arrays
133  FArrayBox fab_Drhs(tbxp3,1,The_Async_Arena());
134  auto Drhs=fab_Drhs.array();
135 
136  auto DUon = mf_DUon.array(mfi);
137  auto DVom = mf_DVom.array(mfi);
138 
139  ParallelFor(makeSlab(tbxp3,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
140  {
141  Drhs(i,j,0)=zeta(i,j,0,krhs)+h(i,j,0);
142  });
143 
144  ParallelFor(makeSlab(xgbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
145  {
146  Real on_u = 2.0_rt / (pn(i,j,0)+pn(i-1,j,0));
147  Real cff1= 0.5_rt * on_u *(Drhs(i,j,0)+Drhs(i-1,j,0));
148  DUon(i,j,0)=ubar(i,j,0,krhs)*cff1;
149  });
150 
151  ParallelFor(makeSlab(ygbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
152  {
153  Real om_v = 2.0_rt / (pm(i,j,0)+pm(i,j-1,0));
154  Real cff1= 0.5_rt * om_v * (Drhs(i,j,0)+Drhs(i,j-1,0));
155  DVom(i,j,0)=vbar(i,j,0,krhs)*cff1;
156  });
157  }
158 
159  // These are needed to pass the tests with bathymetry but I don't quite see why
160  mf_DUon.FillBoundary(geom[lev].periodicity());
161  mf_DVom.FillBoundary(geom[lev].periodicity());
162 
163  for ( MFIter mfi(*mf_rhoS, TilingIfNotGPU()); mfi.isValid(); ++mfi )
164  {
165  Array4<Real const> const& rhoS = mf_rhoS->const_array(mfi);
166  Array4<Real const> const& rhoA = mf_rhoA->const_array(mfi);
167  Array4<Real const> const& h = mf_h->const_array(mfi);
168 
169  Array4<Real > const& rufrc = mf_rufrc->array(mfi);
170  Array4<Real > const& rvfrc = mf_rvfrc->array(mfi);
171  Array4<Real > const& Zt_avg1 = mf_Zt_avg1->array(mfi);
172  Array4<Real > const& ubar = mf_ubar->array(mfi);
173  Array4<Real > const& vbar = mf_vbar->array(mfi);
174  Array4<Real > const& zeta = mf_zeta->array(mfi);
175  Array4<Real > const& DU_avg1 = (mf_DU_avg1)->array(mfi);
176  Array4<Real > const& DU_avg2 = (mf_DU_avg2)->array(mfi);
177  Array4<Real > const& DV_avg1 = (mf_DV_avg1)->array(mfi);
178  Array4<Real > const& DV_avg2 = (mf_DV_avg2)->array(mfi);
179  Array4<Real > const& ru = (mf_ru)->array(mfi);
180  Array4<Real > const& rv = (mf_rv)->array(mfi);
181  Array4<Real > const& rubar = (mf_rubar)->array(mfi);
182  Array4<Real > const& rvbar = (mf_rvbar)->array(mfi);
183  Array4<Real > const& rzeta = (mf_rzeta)->array(mfi);
184  Array4<Real const> const& visc2_p = mf_visc2_p->const_array(mfi);
185  Array4<Real const> const& visc2_r = mf_visc2_r->const_array(mfi);
186 
187  Array4<Real const> const& pm = mf_pm->const_array(mfi);
188  Array4<Real const> const& pn = mf_pn->const_array(mfi);
189  Array4<Real const> const& fcor = mf_fcor->const_array(mfi);
190 
191  Box bx = mfi.tilebox();
192  Box gbx = mfi.growntilebox();
193  Box gbx1 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
194  Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
195  Box gbx3 = mfi.growntilebox(IntVect(NGROW+1,NGROW+1,0));
196  Box xgbx2 = mfi.grownnodaltilebox(0, IntVect(NGROW,NGROW,0));
197  Box ygbx2 = mfi.grownnodaltilebox(1, IntVect(NGROW,NGROW,0));
198 
199  Box xbxD = mfi.nodaltilebox(0);
200  xbxD.makeSlab(2,0);
201 
202  Box ybxD = mfi.nodaltilebox(1);
203  ybxD.makeSlab(2,0);
204 
205  Box tbxp1 = bx; tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
206  Box tbxp11 = bx; tbxp11.grow(IntVect(NGROW-1,NGROW-1,NGROW-1));
207  Box tbxp2 = bx; tbxp2.grow(IntVect(NGROW,NGROW,0));
208  Box tbxp3 = bx; tbxp3.grow(IntVect(NGROW+1,NGROW+1,0));
209 
210  Box bxD = bx; bxD.makeSlab(2,0);
211  Box gbxD = gbx; gbxD.makeSlab(2,0);
212  Box gbx1D = gbx1; gbx1D.makeSlab(2,0);
213  Box gbx2D = gbx2; gbx2D.makeSlab(2,0);
214 
215  Box tbxp2D = tbxp2;
216  tbxp2D.makeSlab(2,0);
217 
218  FArrayBox fab_fomn(tbxp2,1,The_Async_Arena());
219 
220  //step2d work arrays
221  FArrayBox fab_Drhs(tbxp3,1,The_Async_Arena());
222  FArrayBox fab_Dnew(tbxp2,1,The_Async_Arena());
223  FArrayBox fab_zwrk(tbxp1,1,The_Async_Arena());
224  FArrayBox fab_gzeta(tbxp1,1,The_Async_Arena());
225  FArrayBox fab_gzeta2(tbxp1,1,The_Async_Arena());
226  FArrayBox fab_gzetaSA(tbxp1,1,The_Async_Arena());
227  FArrayBox fab_Dstp(tbxp3,1,The_Async_Arena());
228  FArrayBox & fab_DUon=mf_DUon[mfi];
229  FArrayBox & fab_DVom=mf_DVom[mfi];
230  FArrayBox fab_rhs_ubar(xbxD,1,The_Async_Arena());
231  FArrayBox fab_rhs_vbar(ybxD,1,The_Async_Arena());
232  FArrayBox fab_rhs_zeta(tbxp1,1,The_Async_Arena());
233  FArrayBox fab_zeta_new(tbxp1,1,The_Async_Arena());
234 
235  auto fomn=fab_fomn.array();
236 
237  auto Drhs = fab_Drhs.array();
238  auto Drhs_const = fab_Drhs.const_array();
239  auto Dnew=fab_Dnew.array();
240  auto zwrk=fab_zwrk.array();
241  auto gzeta=fab_gzeta.array();
242  auto gzeta2=fab_gzeta2.array();
243  auto gzetaSA=fab_gzetaSA.array();
244  auto Dstp=fab_Dstp.array();
245  auto DUon=fab_DUon.array();
246  auto DVom=fab_DVom.array();
247  auto rhs_ubar=fab_rhs_ubar.array();
248  auto rhs_vbar=fab_rhs_vbar.array();
249  auto rhs_zeta=fab_rhs_zeta.array();
250  auto zeta_new=fab_zeta_new.array();
251 
252  auto weight1 = vec_weight1.dataPtr();
253  auto weight2 = vec_weight2.dataPtr();
254 
255  //From ana_grid.h and metrics.F
256  ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int)
257  {
258  rhs_ubar(i,j,0)=0.0_rt;
259  });
260 
261  ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int)
262  {
263  rhs_vbar(i,j,0)=0.0_rt;
264  });
265 
267  ParallelFor(tbxp2D, [=] AMREX_GPU_DEVICE (int i, int j, int )
268  {
269  fomn(i,j,0) = fcor(i,j,0)*(1.0/(pm(i,j,0)*pn(i,j,0)));
270  });
271  }
272 
273  ParallelFor(makeSlab(tbxp3,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
274  {
275  Drhs(i,j,0)=zeta(i,j,0,krhs)+h(i,j,0);
276  });
277 
278  if(predictor_2d_step)
279  {
280  if(first_2d_step) {
281  Real cff2=(-1.0_rt/12.0_rt)*weight2[my_iif+1];
282  ParallelFor(makeSlab(gbx3,2,0),
283  [=] AMREX_GPU_DEVICE (int i, int j, int)
284  {
285  Zt_avg1(i,j,0)=0.0_rt;
286  });
287  ParallelFor(makeSlab(xgbx2,2,0),
288  [=] AMREX_GPU_DEVICE (int i, int j, int)
289  {
290  DU_avg1(i,j,0)=0.0_rt;
291  DU_avg2(i,j,0)=cff2*DUon(i,j,0);
292  });
293  ParallelFor(makeSlab(ygbx2,2,0),
294  [=] AMREX_GPU_DEVICE (int i, int j, int)
295  {
296  DV_avg1(i,j,0)=0.0_rt;
297  DV_avg2(i,j,0)=cff2*DVom(i,j,0);
298  });
299  }
300  else {
301  Real cff1_wt1 = weight1[my_iif-1];
302  Real cff2_wt1 = (8.0_rt/12.0_rt)*weight2[my_iif]-
303  (1.0_rt/12.0_rt)*weight2[my_iif+1];
304 
305  ParallelFor(makeSlab(gbx3,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
306  {
307  Zt_avg1(i,j,0) += cff1_wt1*zeta(i,j,0,krhs);
308  });
309 
310  ParallelFor(makeSlab(xgbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
311  {
312  DU_avg1(i,j,0) += cff1_wt1*DUon(i,j,0);
313  DU_avg2(i,j,0) += cff2_wt1*DUon(i,j,0);
314  });
315 
316  ParallelFor(makeSlab(ygbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
317  {
318  DV_avg1(i,j,0) += cff1_wt1*DVom(i,j,0);
319  DV_avg2(i,j,0) += cff2_wt1*DVom(i,j,0);
320  });
321  }
322  }
323  else {
324  Real cff2_wt2;
325 
326  if (first_2d_step) {
327  cff2_wt2=weight2[my_iif];
328  } else {
329  cff2_wt2=5.0_rt/12.0_rt*weight2[my_iif];
330  }
331 
332  ParallelFor(makeSlab(xgbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
333  {
334  DU_avg2(i,j,0)=DU_avg2(i,j,0)+cff2_wt2*DUon(i,j,0);
335  });
336 
337  ParallelFor(makeSlab(ygbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
338  {
339  DV_avg2(i,j,0)=DV_avg2(i,j,0)+cff2_wt2*DVom(i,j,0);
340  });
341  }
342  //
343  // Do not perform the actual time stepping during the auxiliary
344  // (nfast(ng)+1) time step. Jump to next box
345  //
346 
347  if (my_iif>=nfast) {
348  continue; }
349  //Load new free-surface values into shared array at both predictor
350  //and corrector steps
351  //
352  //=======================================================================
353  // Time step free-surface equation.
354  //=======================================================================
355  //
356  // During the first time-step, the predictor step is Forward-Euler
357  // and the corrector step is Backward-Euler. Otherwise, the predictor
358  // step is Leap-frog and the corrector step is Adams-Moulton.
359  //
360 
361  // todo: gzeta
362 
363  // todo: HACKHACKHACK Should use rho0 from prob.H
364  Real fac=1000.0_rt/1025.0_rt;
365 
366  if (my_iif==0) {
367  Real cff1=dtfast_lev;
368 
369  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int )
370  {
371  rhs_zeta(i,j,0) = (DUon(i,j,0)-DUon(i+1,j,0))+
372  (DVom(i,j,0)-DVom(i,j+1,0));
373  zeta_new(i,j,0) = zeta(i,j,0,kstp)+ pm(i,j,0)*pn(i,j,0)*cff1*rhs_zeta(i,j,0);
374  Dnew(i,j,0) = zeta_new(i,j,0)+h(i,j,0);
375 
376  //Pressure gradient terms:
377  zwrk(i,j,0)=0.5_rt*(zeta(i,j,0,kstp)+zeta_new(i,j,0));
378  gzeta(i,j,0)=(fac+rhoS(i,j,0))*zwrk(i,j,0);
379  gzeta2(i,j,0)=gzeta(i,j,0)*zwrk(i,j,0);
380  gzetaSA(i,j,0)=zwrk(i,j,0)*(rhoS(i,j,0)-rhoA(i,j,0));
381  });
382 
383  } else if (predictor_2d_step) {
384 
385  Real cff1=2.0_rt * dtfast_lev;
386  Real cff4=4.0_rt / 25.0_rt;
387  Real cff5=1.0_rt - 2.0_rt*cff4;
388 
389  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int )
390  {
391  rhs_zeta(i,j,0)=(DUon(i,j,0)-DUon(i+1,j,0))+
392  (DVom(i,j,0)-DVom(i,j+1,0));
393  zeta_new(i,j,0)=zeta(i,j,0,kstp)+
394  pm(i,j,0)*pn(i,j,0)*cff1*rhs_zeta(i,j,0);
395  Dnew(i,j,0)=zeta_new(i,j,0)+h(i,j,0);
396  //Pressure gradient terms
397  zwrk(i,j,0)=cff5*zeta(i,j,0,krhs)+
398  cff4*(zeta(i,j,0,kstp)+zeta_new(i,j,0));
399  gzeta(i,j,0)=(fac+rhoS(i,j,0))*zwrk(i,j,0);
400  gzeta2(i,j,0)=gzeta(i,j,0)*zwrk(i,j,0);
401  gzetaSA(i,j,0)=zwrk(i,j,0)*(rhoS(i,j,0)-rhoA(i,j,0));
402  });
403 
404  } else if (!predictor_2d_step) { //AKA if(corrector_2d_step)
405 
406  Real cff1=dtfast_lev * 5.0_rt/12.0_rt;
407  Real cff2=dtfast_lev * 8.0_rt/12.0_rt;
408  Real cff3=dtfast_lev * 1.0_rt/12.0_rt;
409  Real cff4=2.0_rt/5.0_rt;
410  Real cff5=1.0_rt-cff4;
411 
412  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int )
413  {
414  Real cff=cff1*((DUon(i,j,0)-DUon(i+1,j,0))+
415  (DVom(i,j,0)-DVom(i,j+1,0)));
416  zeta_new(i,j,0)=zeta(i,j,0,kstp)+
417  pm(i,j,0)*pn(i,j,0)*(cff+
418  cff2*rzeta(i,j,0,kstp)-
419  cff3*rzeta(i,j,0,ptsk));
420  Dnew(i,j,0)=zeta_new(i,j,0)+h(i,j,0);
421  //Pressure gradient terms
422  zwrk(i,j,0)=cff5*zeta_new(i,j,0)+cff4*zeta(i,j,0,krhs);
423  gzeta(i,j,0)=(fac+rhoS(i,j,0))*zwrk(i,j,0);
424  gzeta2(i,j,0)=gzeta(i,j,0)*zwrk(i,j,0);
425  gzetaSA(i,j,0)=zwrk(i,j,0)*(rhoS(i,j,0)-rhoA(i,j,0));
426  });
427  }
428 
429  //
430  // Load new free-surface values into shared array at both predictor
431  // and corrector steps.
432  //
433  //// zeta(knew) only valid at zeta_new, i.e. tbxp1
434  ParallelFor(gbx1,
435  [=] AMREX_GPU_DEVICE (int i, int j, int )
436  {
437  zeta(i,j,0,knew) = zeta_new(i,j,0);
438  });
439 
440  //
441  // If predictor step, load right-side-term into shared array.
442  //
443  if (predictor_2d_step) {
444  ParallelFor(gbx1, [=] AMREX_GPU_DEVICE (int i, int j, int )
445  {
446  rzeta(i,j,0,krhs)=rhs_zeta(i,j,0);
447  });
448  }
449 
450  //
451  //=======================================================================
452  // Compute right-hand-side for the 2D momentum equations.
453  //=======================================================================
454  //
455 /*
456 !
457 !-----------------------------------------------------------------------
458 ! Compute pressure gradient terms.
459 !-----------------------------------------------------------------------
460 !
461 */
462 
463  Real cff1 = 0.5_rt * solverChoice.g; // Should be the variable gravitational field strength
464  Real cff2 = 1.0_rt / 3.0_rt;
465  ParallelFor(xbxD,
466  [=] AMREX_GPU_DEVICE (int i, int j, int )
467  {
468  Real on_u = 2.0_rt / (pn(i,j,0)+pn(i-1,j,0));
469  rhs_ubar(i,j,0)=cff1 * on_u *
470  (( h(i-1,j,0) + h(i,j,0))*
471  (gzeta(i-1,j,0) - gzeta(i,j,0))+
472  ( h(i-1,j,0) - h(i,j,0))*
473  ( gzetaSA(i-1,j,0) + gzetaSA(i,j,0)+
474  cff2*( rhoA(i-1,j,0) - rhoA(i,j,0))*
475  ( zwrk(i-1,j,0) - zwrk(i,j,0)))+
476  (gzeta2(i-1,j,0)- gzeta2(i ,j,0)));
477  });
478 
479  ParallelFor(ybxD,
480  [=] AMREX_GPU_DEVICE (int i, int j, int )
481  {
482  Real om_v = 2.0_rt / (pm(i,j,0)+pm(i,j-1,0));
483  rhs_vbar(i,j,0) = cff1*om_v *
484  (( h(i,j-1,0) + h(i,j,0))*
485  (gzeta(i,j-1,0) - gzeta(i,j,0))+
486  ( h(i,j-1,0) - h(i,j,0))*
487  (gzetaSA(i,j-1,0)+ gzetaSA(i,j ,0)+
488  cff2*(rhoA(i,j-1,0)- rhoA(i,j ,0))*
489  (zwrk(i,j-1,0)- zwrk(i,j ,0)))+
490  (gzeta2(i,j-1,0)- gzeta2(i,j ,0)));
491  });
492 
493  // Advection terms for 2d ubar, vbar added to rhs_ubar and rhs_vbar
494  //
495  //-----------------------------------------------------------------------
496  // rhs_uv_2d
497  //-----------------------------------------------------------------------
498  //
499  Array4<Real const> const& ubar_const = mf_ubar->const_array(mfi);
500  Array4<Real const> const& vbar_const = mf_vbar->const_array(mfi);
501  rhs_uv_2d(xbxD, ybxD, ubar_const, vbar_const, rhs_ubar, rhs_vbar, DUon, DVom, krhs);
502 
503  //-----------------------------------------------------------------------
504  // Add Coriolis forcing
505  //-----------------------------------------------------------------------
507  // Coriolis terms for 2d ubar, vbar added to rhs_ubar and rhs_vbar
508  //
509  //-----------------------------------------------------------------------
510  // coriolis
511  //-----------------------------------------------------------------------
512  //
513  coriolis(xbxD, ybxD, ubar_const, vbar_const, rhs_ubar, rhs_vbar, Drhs, fomn, krhs, 0);
514  }
515 
516  //-----------------------------------------------------------------------
517  //Add in horizontal harmonic viscosity.
518  // Consider generalizing or copying uv3dmix, where Drhs is used instead of Hz and u=>ubar v=>vbar, drop dt terms
519  //-----------------------------------------------------------------------
520  uv3dmix(xbxD, ybxD, ubar, vbar, ubar, vbar, rhs_ubar, rhs_vbar,
521  visc2_p, visc2_r, Drhs_const,
522  pn, pm, krhs, nnew, 0.0_rt);
523 
524  //-----------------------------------------------------------------------
525  // Coupling from 3d to 2d
526  //-----------------------------------------------------------------------
527  if (first_2d_step&&predictor_2d_step)
528  {
529  if (iic==ntfirst) {
530 
531  ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
532  {
533  rufrc(i,j,0) -= rhs_ubar(i,j,0);
534  rhs_ubar(i,j,0) += rufrc(i,j,0);
535  ru(i,j,-1,nstp) = rufrc(i,j,0);
536  });
537 
538  ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
539  {
540  rvfrc(i,j,0) -= rhs_vbar(i,j,0);
541  rhs_vbar(i,j,0) += rvfrc(i,j,0);
542  rv(i,j,-1,nstp) = rvfrc(i,j,0);
543  });
544 
545  } else if (iic==(ntfirst+1)) {
546 
547  ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
548  {
549  rufrc(i,j,0)=rufrc(i,j,0)-rhs_ubar(i,j,0);
550  rhs_ubar(i,j,0)=rhs_ubar(i,j,0)+1.5_rt*rufrc(i,j,0)-0.5_rt*ru(i,j,-1,0);
551  ru(i,j,-1,1)=rufrc(i,j,0);
552  Real r_swap= ru(i,j,-1,1);
553  ru(i,j,-1,1) = ru(i,j,-1,0);
554  ru(i,j,-1,0) = r_swap;
555  });
556 
557  ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
558  {
559  rvfrc(i,j,0)=rvfrc(i,j,0)-rhs_vbar(i,j,0);
560  rhs_vbar(i,j,0)=rhs_vbar(i,j,0)+1.5_rt*rvfrc(i,j,0)-0.5_rt*rv(i,j,-1,0);
561  rv(i,j,-1,1)=rvfrc(i,j,0);
562  Real r_swap= rv(i,j,-1,1);
563  rv(i,j,-1,1) = rv(i,j,-1,0);
564  rv(i,j,-1,0) = r_swap;
565  });
566 
567  } else {
568  cff1=23.0_rt/12.0_rt;
569  cff2=16.0_rt/12.0_rt;
570  Real cff3= 5.0_rt/12.0_rt;
571 
572  ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
573  {
574  rufrc(i,j,0)=rufrc(i,j,0)-rhs_ubar(i,j,0);
575  rhs_ubar(i,j,0)=rhs_ubar(i,j,0)+
576  cff1*rufrc(i,j,0)-
577  cff2*ru(i,j,-1,0)+
578  cff3*ru(i,j,-1,1);
579  ru(i,j,-1,1)=rufrc(i,j,0);
580  Real r_swap= ru(i,j,-1,1);
581  ru(i,j,-1,1) = ru(i,j,-1,0);
582  ru(i,j,-1,0) = r_swap;
583  });
584 
585  ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
586  {
587  rvfrc(i,j,0)=rvfrc(i,j,0)-rhs_vbar(i,j,0);
588  rhs_vbar(i,j,0)=rhs_vbar(i,j,0)+
589  cff1*rvfrc(i,j,0)-
590  cff2*rv(i,j,-1,0)+
591  cff3*rv(i,j,-1,1);
592  rv(i,j,-1,1)=rvfrc(i,j,0);
593 
594  Real r_swap= rv(i,j,-1,1);
595  rv(i,j,-1,1) = rv(i,j,-1,0);
596  rv(i,j,-1,0) = r_swap;
597  });
598  }
599  } else {
600 
601  ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
602  {
603  rhs_ubar(i,j,0) += rufrc(i,j,0);
604  });
605 
606  ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
607  {
608  rhs_vbar(i,j,0) += rvfrc(i,j,0);
609  });
610  }
611 
612  //
613  //=======================================================================
614  // Time step 2D momentum equations.
615  //=======================================================================
616  //
617  // Compute total water column depth.
618  //
619  ParallelFor(makeSlab(tbxp3,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
620  {
621  Dstp(i,j,0)=zeta(i,j,0,kstp)+h(i,j,0);
622  });
623 
624  //
625  // During the first time-step, the predictor step is Forward-Euler
626  // and the corrector step is Backward-Euler. Otherwise, the predictor
627  // step is Leap-frog and the corrector step is Adams-Moulton.
628  //
629  if (my_iif==0) {
630  cff1=0.5_rt*dtfast_lev;
631  ParallelFor(xbxD,
632  [=] AMREX_GPU_DEVICE (int i, int j, int )
633  {
634  Real cff=(pm(i,j,0)+pm(i-1,j,0))*(pn(i,j,0)+pn(i-1,j,0));
635  Real Dnew_avg =1.0_rt/(Dnew(i,j,0)+Dnew(i-1,j,0));
636  ubar(i,j,0,knew)=(ubar(i,j,0,kstp)*
637  (Dstp(i,j,0)+Dstp(i-1,j,0))+
638  cff*cff1*rhs_ubar(i,j,0))*Dnew_avg;
639  });
640  ParallelFor(ybxD,
641  [=] AMREX_GPU_DEVICE (int i, int j, int )
642  {
643  Real cff=(pm(i,j,0)+pm(i,j-1,0))*(pn(i,j,0)+pn(i,j-1,0));
644  Real Dnew_avg=1.0_rt/(Dnew(i,j,0)+Dnew(i,j-1,0));
645  vbar(i,j,0,knew)=(vbar(i,j,0,kstp)*
646  (Dstp(i,j,0)+Dstp(i,j-1,0))+
647  cff*cff1*rhs_vbar(i,j,0))*Dnew_avg;
648  });
649 
650  } else if (predictor_2d_step) {
651 
652  cff1=dtfast_lev;
653  ParallelFor(xbxD,
654  [=] AMREX_GPU_DEVICE (int i, int j, int )
655  {
656  Real cff=(pm(i,j,0)+pm(i-1,j,0))*(pn(i,j,0)+pn(i-1,j,0));
657  Real Dnew_avg=1.0_rt/(Dnew(i,j,0)+Dnew(i-1,j,0));
658  ubar(i,j,0,knew)=(ubar(i,j,0,kstp)*
659  (Dstp(i,j,0)+Dstp(i-1,j,0))+
660  cff*cff1*rhs_ubar(i,j,0))*Dnew_avg;
661  });
662  ParallelFor(ybxD,
663  [=] AMREX_GPU_DEVICE (int i, int j, int )
664  {
665  Real cff=(pm(i,j,0)+pm(i,j-1,0))*(pn(i,j,0)+pn(i,j-1,0));
666  Real Dnew_avg=1.0_rt/(Dnew(i,j,0)+Dnew(i,j-1,0));
667  vbar(i,j,0,knew)=(vbar(i,j,0,kstp)*
668  (Dstp(i,j,0)+Dstp(i,j-1,0))+
669  cff*cff1*rhs_vbar(i,j,0))*Dnew_avg;
670  });
671 
672  } else if ((!predictor_2d_step)) {
673 
674  cff1=0.5_rt*dtfast_lev*5.0_rt/12.0_rt;
675  cff2=0.5_rt*dtfast_lev*8.0_rt/12.0_rt;
676  Real cff3=0.5_rt*dtfast_lev*1.0_rt/12.0_rt;
677  ParallelFor(xbxD,
678  [=] AMREX_GPU_DEVICE (int i, int j, int )
679  {
680  Real cff=(pm(i,j,0)+pm(i-1,j,0))*(pn(i,j,0)+pn(i-1,j,0));
681  Real Dnew_avg=1.0_rt/(Dnew(i,j,0)+Dnew(i-1,j,0));
682  ubar(i,j,0,knew)=(ubar(i,j,0,kstp)*
683  (Dstp(i,j,0)+Dstp(i-1,j,0))+
684  cff*(cff1*rhs_ubar(i,j,0)+
685  cff2*rubar(i,j,0,kstp)-
686  cff3*rubar(i,j,0,ptsk)))*Dnew_avg;
687  });
688  ParallelFor(ybxD,
689  [=] AMREX_GPU_DEVICE (int i, int j, int )
690  {
691  Real cff=(pm(i,j,0)+pm(i,j-1,0))*(pn(i,j,0)+pn(i,j-1,0));
692  Real Dnew_avg=1.0_rt/(Dnew(i,j,0)+Dnew(i,j-1,0));
693  vbar(i,j,0,knew)=(vbar(i,j,0,kstp)*
694  (Dstp(i,j,0)+Dstp(i,j-1,0))+
695  cff*(cff1*rhs_vbar(i,j,0)+
696  cff2*rvbar(i,j,0,kstp)-
697  cff3*rvbar(i,j,0,ptsk)))*Dnew_avg;
698  });
699  }
700 
701  //store rhs_ubar and rhs_vbar to save later
702  //
703  // If predictor step, load right-side-term into shared arrays for
704  // future use during the subsequent corrector step.
705  //
706 
707  if (predictor_2d_step) {
708  ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
709  {
710  rubar(i,j,0,krhs)=rhs_ubar(i,j,0);
711  });
712  ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
713  {
714  rvbar(i,j,0,krhs)=rhs_vbar(i,j,0);
715  });
716  }
717  }
718 }
#define NGROW
Definition: IndexDefines.H:13
void rhs_uv_2d(const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real const > &Duon, const amrex::Array4< amrex::Real const > &Dvom, const int nrhs)
Definition: REMORA_rhs_uv_2d.cpp:20
void uv3dmix(const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real > &u, const amrex::Array4< amrex::Real > &v, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &rufrc, const amrex::Array4< amrex::Real > &rvfrc, const amrex::Array4< amrex::Real const > &visc2_p, const amrex::Array4< amrex::Real const > &visc2_r, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, int nrhs, int nnew, const amrex::Real dt_lev)
Definition: REMORA_uv3dmix.cpp:6
amrex::Vector< amrex::Real > vec_weight2
Definition: REMORA.H:299
amrex::Vector< amrex::Real > vec_weight1
Definition: REMORA.H:298
void coriolis(const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &fomn, int nrhs, int nr)
Definition: REMORA_coriolis.cpp:10
@ vbar
Definition: IndexDefines.H:39
@ ubar
Definition: IndexDefines.H:38
@ zeta
Definition: IndexDefines.H:40
bool use_coriolis
Definition: DataStruct.H:194
amrex::Real g
Definition: DataStruct.H:234

◆ advance_2d_onestep()

void REMORA::advance_2d_onestep ( int  lev,
amrex::Real  dt_lev,
amrex::Real  dtfast_lev,
int  my_iif,
int  nfast_counter 
)

2D advance, one predictor/corrector step

7 {
8  bool first_2d_step=(my_iif==0);
9 
10  // These are needed to pass ctests
11  Real dummy_time = 0.0;
12  FillPatch(lev, dummy_time, *vec_ubar[lev], GetVecOfPtrs(vec_ubar), BdyVars::ubar);
13  FillPatch(lev, dummy_time, *vec_vbar[lev], GetVecOfPtrs(vec_vbar), BdyVars::vbar);
14 
15  //Predictor
16  bool predictor_2d_step=true;
17  int next_indx1 = 0;
18  advance_2d(lev,
19  vec_rhoS[lev].get() , vec_rhoA[lev].get(),
20  vec_ru[lev].get() , vec_rv[lev].get(),
21  vec_rufrc[lev].get(), vec_rvfrc[lev].get(),
22  vec_Zt_avg1[lev].get(),
23  vec_DU_avg1[lev], vec_DU_avg2[lev],
24  vec_DV_avg1[lev], vec_DV_avg2[lev],
25  vec_rubar[lev], vec_rvbar[lev], vec_rzeta[lev],
26  vec_ubar[lev], vec_vbar[lev], vec_zeta[lev].get(),
27  vec_hOfTheConfusingName[lev].get(),
28  vec_pm[lev].get(), vec_pn[lev].get(),
29  vec_fcor[lev].get(),
30  vec_visc2_p[lev].get(), vec_visc2_r[lev].get(),
31  dtfast_lev, predictor_2d_step, first_2d_step, my_iif, next_indx1);
32 
33  //Corrector. Skip it on last fast step
34  predictor_2d_step=false;
35  if (my_iif < nfast_counter - 1) {
36 
37  // These are needed to pass ctests
38  FillPatch(lev, dummy_time, *vec_ubar[lev], GetVecOfPtrs(vec_ubar), BdyVars::ubar);
39  FillPatch(lev, dummy_time, *vec_vbar[lev], GetVecOfPtrs(vec_vbar), BdyVars::vbar);
40 
41  advance_2d(lev,
42  vec_rhoS[lev].get(), vec_rhoA[lev].get(),
43  vec_ru[lev].get(), vec_rv[lev].get(),
44  vec_rufrc[lev].get(), vec_rvfrc[lev].get(),
45  vec_Zt_avg1[lev].get(),
46  vec_DU_avg1[lev], vec_DU_avg2[lev],
47  vec_DV_avg1[lev], vec_DV_avg2[lev],
48  vec_rubar[lev], vec_rvbar[lev], vec_rzeta[lev],
49  vec_ubar[lev], vec_vbar[lev], vec_zeta[lev].get(),
50  vec_hOfTheConfusingName[lev].get(),
51  vec_pm[lev].get(), vec_pn[lev].get(),
52  vec_fcor[lev].get(),
53  vec_visc2_p[lev].get(), vec_visc2_r[lev].get(),
54  dtfast_lev, predictor_2d_step, first_2d_step, my_iif, next_indx1);
55  }
56 }
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_fcor
Definition: REMORA.H:288
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_hOfTheConfusingName
Definition: REMORA.H:197
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rubar
Definition: REMORA.H:269
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pm
Definition: REMORA.H:282
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_DU_avg2
Definition: REMORA.H:263
void advance_2d(int lev, amrex::MultiFab const *mf_rhoS, amrex::MultiFab const *mf_rhoA, amrex::MultiFab *mf_ru, amrex::MultiFab *mf_rv, amrex::MultiFab *mf_rufrc, amrex::MultiFab *mf_rvfrc, amrex::MultiFab *mf_Zt_avg1, std::unique_ptr< amrex::MultiFab > &mf_DU_avg1, std::unique_ptr< amrex::MultiFab > &mf_DU_avg2, std::unique_ptr< amrex::MultiFab > &mf_DV_avg1, std::unique_ptr< amrex::MultiFab > &mf_DV_avg2, std::unique_ptr< amrex::MultiFab > &mf_rubar, std::unique_ptr< amrex::MultiFab > &mf_rvbar, std::unique_ptr< amrex::MultiFab > &mf_rzeta, std::unique_ptr< amrex::MultiFab > &mf_ubar, std::unique_ptr< amrex::MultiFab > &mf_vbar, amrex::MultiFab *mf_zeta, amrex::MultiFab const *mf_h, amrex::MultiFab const *mf_pm, amrex::MultiFab const *mf_pn, amrex::MultiFab const *mf_fcor, amrex::MultiFab const *mf_visc2_p, amrex::MultiFab const *mf_visc2_r, const amrex::Real dtfast_lev, const bool predictor_2d_step, const bool first_2d_step, int my_iif, int &next_indx1)
Definition: REMORA_advance_2d.cpp:37
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rvfrc
Definition: REMORA.H:212
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rufrc
Definition: REMORA.H:210
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_visc2_p
Definition: REMORA.H:218
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rvbar
Definition: REMORA.H:271
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rhoS
Definition: REMORA.H:295
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_visc2_r
Definition: REMORA.H:220
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rhoA
Definition: REMORA.H:296
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_DV_avg1
Definition: REMORA.H:265
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_ru
Definition: REMORA.H:206
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_zeta
Definition: REMORA.H:279
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_vbar
Definition: REMORA.H:277
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_DU_avg1
Definition: REMORA.H:261
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_ubar
Definition: REMORA.H:275
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_DV_avg2
Definition: REMORA.H:267
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rzeta
Definition: REMORA.H:273
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pn
Definition: REMORA.H:285
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Zt_avg1
Definition: REMORA.H:243
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rv
Definition: REMORA.H:208
void FillPatch(int lev, amrex::Real time, amrex::MultiFab &mf_to_be_filled, amrex::Vector< amrex::MultiFab * > const &mfs, const int bdy_var_type=BdyVars::null)
Definition: REMORA_FillPatch.cpp:16

◆ advance_3d()

void REMORA::advance_3d ( int  lev,
amrex::MultiFab &  mf_cons,
amrex::MultiFab &  mf_u,
amrex::MultiFab &  mf_v,
amrex::MultiFab *  mf_sstore,
amrex::MultiFab *  mf_ru,
amrex::MultiFab *  mf_rv,
std::unique_ptr< amrex::MultiFab > &  mf_DU_avg1,
std::unique_ptr< amrex::MultiFab > &  mf_DU_avg2,
std::unique_ptr< amrex::MultiFab > &  mf_DV_avg1,
std::unique_ptr< amrex::MultiFab > &  mf_DV_avg2,
std::unique_ptr< amrex::MultiFab > &  mf_ubar,
std::unique_ptr< amrex::MultiFab > &  mf_vbar,
std::unique_ptr< amrex::MultiFab > &  mf_Akv,
std::unique_ptr< amrex::MultiFab > &  mf_Akt,
std::unique_ptr< amrex::MultiFab > &  mf_Hz,
std::unique_ptr< amrex::MultiFab > &  mf_Huon,
std::unique_ptr< amrex::MultiFab > &  mf_Hvom,
std::unique_ptr< amrex::MultiFab > &  mf_z_w,
amrex::MultiFab const *  mf_h,
amrex::MultiFab const *  mf_pm,
amrex::MultiFab const *  mf_pn,
const int  N,
const amrex::Real  dt_lev 
)

Advance the 3D variables

30 {
31  const int nrhs = 0;
32  const int nnew = 0;
33 
34  int iic = istep[lev];
35  int ntfirst = 0;
36 
37  // Because zeta may have changed
38  stretch_transform(lev);
39 
40  // These temporaries used to be made in advance_3d_ml and passed in;
41  // now we make them here
42 
43  const BoxArray& ba = mf_cons.boxArray();
44  const DistributionMapping& dm = mf_cons.DistributionMap();
45 
46  //Only used locally, probably should be rearranged into FArrayBox declaration
47  MultiFab mf_AK (ba,dm,1,IntVect(NGROW,NGROW,0)); //2d missing j coordinate
48  MultiFab mf_DC (ba,dm,1,IntVect(NGROW,NGROW,NGROW-1)); //2d missing j coordinate
49  MultiFab mf_Hzk(ba,dm,1,IntVect(NGROW,NGROW,NGROW-1)); //2d missing j coordinate
50 
51  for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
52  {
53  Array4<Real > const& u = mf_u.array(mfi);
54  Array4<Real > const& v = mf_v.array(mfi);
55 
56  Array4<Real > const& ru = mf_ru->array(mfi);
57  Array4<Real > const& rv = mf_rv->array(mfi);
58 
59  Array4<Real > const& AK = mf_AK.array(mfi);
60  Array4<Real > const& DC = mf_DC.array(mfi);
61 
62  Array4<Real > const& Hzk = mf_Hzk.array(mfi);
63  Array4<Real > const& Akv = mf_Akv->array(mfi);
64 
65  Array4<Real const> const& Hz = mf_Hz->const_array(mfi);
66 
67  Array4<Real const> const& DU_avg1 = mf_DU_avg1->const_array(mfi);
68  Array4<Real const> const& DV_avg1 = mf_DV_avg1->const_array(mfi);
69 
70  Array4<Real> const& DU_avg2 = mf_DU_avg2->array(mfi);
71  Array4<Real> const& DV_avg2 = mf_DV_avg2->array(mfi);
72 
73  Array4<Real> const& ubar = mf_ubar->array(mfi);
74  Array4<Real> const& vbar = mf_vbar->array(mfi);
75 
76  Array4<Real> const& Huon = mf_Huon->array(mfi);
77  Array4<Real> const& Hvom = mf_Hvom->array(mfi);
78 
79  Array4<Real const> const& pm = mf_pm->const_array(mfi);
80  Array4<Real const> const& pn = mf_pn->const_array(mfi);
81 
82  Box bx = mfi.tilebox();
83  Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
84  Box gbx21 = mfi.growntilebox(IntVect(NGROW,NGROW,NGROW-1));
85 
86  Box xbx = mfi.nodaltilebox(0);
87  Box ybx = mfi.nodaltilebox(1);
88 
89  Box gbx2D = gbx2;
90  gbx2D.makeSlab(2,0);
91 
92  Box tbxp1 = bx;
93  Box tbxp11 = bx;
94  Box tbxp2 = bx;
95  tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
96  tbxp2.grow(IntVect(NGROW,NGROW,0));
97  tbxp11.grow(IntVect(NGROW-1,NGROW-1,NGROW-1));
98 
99  FArrayBox fab_FC(gbx2,1,amrex::The_Async_Arena());
100  FArrayBox fab_BC(gbx2,1,amrex::The_Async_Arena());
101  FArrayBox fab_CF(gbx21,1,amrex::The_Async_Arena());
102  FArrayBox fab_W(tbxp2,1,amrex::The_Async_Arena());
103 
104  auto FC = fab_FC.array();
105  auto BC = fab_BC.array();
106  auto CF = fab_CF.array();
107 
108  Real cff;
109  if (iic==ntfirst) {
110  cff=0.25*dt_lev;
111  } else if (iic==ntfirst+1) {
112  cff=0.25*dt_lev*3.0/2.0;
113  } else {
114  cff=0.25*dt_lev*23.0/12.0;
115  }
116 
117  ParallelFor(xbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
118  {
119  u(i,j,k) += cff * (pm(i,j,0)+pm(i-1,j,0)) * (pn(i,j,0)+pn(i-1,j,0)) * ru(i,j,k,nrhs);
120  u(i,j,k) *= 2.0 / (Hz(i-1,j,k) + Hz(i,j,k));
121  });
122 
123  ParallelFor(ybx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
124  {
125  v(i,j,k) += cff * (pm(i,j,0)+pm(i,j-1,0)) * (pn(i,j,0)+pn(i,j-1,0)) * rv(i,j,k,nrhs);
126  v(i,j,k) *= 2.0 / (Hz(i,j-1,k) + Hz(i,j,k));
127  });
128 
129  // NOTE: DC is only used as scratch in vert_visc_3d -- no need to pass or return a value
130  // NOTE: may not actually need to set these to zero
131 
132  // Reset to zero on the box on which they'll be used
133  mf_DC[mfi].template setVal<RunOn::Device>(0.,xbx);
134  fab_CF.template setVal<RunOn::Device>(0.,xbx);
135 
136  vert_visc_3d(xbx,1,0,u,Hz,Hzk,AK,Akv,BC,DC,FC,CF,nnew,N,dt_lev);
137 
138  // Reset to zero on the box on which they'll be used
139  mf_DC[mfi].template setVal<RunOn::Device>(0.,ybx);
140  fab_CF.template setVal<RunOn::Device>(0.,ybx);
141 
142  vert_visc_3d(ybx,0,1,v,Hz,Hzk,AK,Akv,BC,DC,FC,CF,nnew,N,dt_lev);
143 
144  // Reset to zero on the box on which they'll be used
145  mf_DC[mfi].template setVal<RunOn::Device>(0.,xbx);
146  fab_CF.template setVal<RunOn::Device>(0.,xbx);
147 
148  vert_mean_3d(xbx,1,0,u,Hz,DU_avg1,DC,CF,pm,nnew,N);
149 
150  // Reset to zero on the box on which they'll be used
151  mf_DC[mfi].template setVal<RunOn::Device>(0.,ybx);
152  fab_CF.template setVal<RunOn::Device>(0.,ybx);
153 
154  vert_mean_3d(ybx,0,1,v,Hz,DV_avg1,DC,CF,pn,nnew,N);
155 
156 #if 0
157  // Reset to zero on the box on which they'll be used
158  mf_DC[mfi].template setVal<RunOn::Device>(0.,grow(xbx,IntVect(0,0,1)));
159  fab_CF.template setVal<RunOn::Device>(0.,grow(xbx,IntVect(0,0,1)));
160 
161  update_massflux_3d(xbx,1,0,u,ubar,Huon,Hz,pn,DU_avg1,DU_avg2,DC,FC,nnew);
162 
163  // Reset to zero on the box on which they'll be used
164  mf_DC[mfi].template setVal<RunOn::Device>(0.,grow(ybx,IntVect(0,0,1)));
165  fab_CF.template setVal<RunOn::Device>(0.,grow(ybx,IntVect(0,0,1)));
166 
167  update_massflux_3d(ybx,0,1,v,vbar,Hvom,Hz,pm,DV_avg1,DV_avg2,DC,FC,nnew);
168 
169 #else
170  // Reset to zero on the box on which they'll be used
171  fab_FC.template setVal<RunOn::Device>(0.,gbx2);
172  mf_DC[mfi].template setVal<RunOn::Device>(0.,grow(gbx2,IntVect(0,0,1)));
173  update_massflux_3d(gbx2,1,0,u,ubar,Huon,Hz,pn,DU_avg1,DU_avg2,DC,FC,nnew);
174 
175  // Reset to zero on the box on which they'll be used
176  fab_FC.template setVal<RunOn::Device>(0.,gbx2);
177  mf_DC[mfi].template setVal<RunOn::Device>(0.,grow(gbx2,IntVect(0,0,1)));
178  update_massflux_3d(gbx2,0,1,v,vbar,Hvom,Hz,pm,DV_avg1,DV_avg2,DC,FC,nnew);
179 #endif
180  }
181 
182  // WE BELIEVE THESE VALUES SHOULD ALREADY BE FILLED
183  // mf_Huon->FillBoundary(geom[lev].periodicity());
184  // mf_Hvom->FillBoundary(geom[lev].periodicity());
185 
186  // ************************************************************************
187  // This should fill both temp and salt with temp/salt currently in cons_old
188  // ************************************************************************
189 
190  for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
191  {
192  Array4<Real> const& Hz = mf_Hz->array(mfi);
193 
194  Array4<Real> const& Huon = mf_Huon->array(mfi);
195  Array4<Real> const& Hvom = mf_Hvom->array(mfi);
196 
197  Array4<Real const> const& z_w = mf_z_w->const_array(mfi);
198  Array4<Real const> const& h = mf_h->const_array(mfi);
199  Array4<Real const> const& pm = mf_pm->const_array(mfi);
200  Array4<Real const> const& pn = mf_pn->const_array(mfi);
201 
202  Box bx = mfi.tilebox();
203  Box gbx = mfi.growntilebox();
204  Box gbx1 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
205  Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
206  Box gbx21 = mfi.growntilebox(IntVect(NGROW,NGROW,NGROW-1));
207 
208  Box tbxp1 = bx;
209  Box tbxp11 = bx;
210  Box tbxp2 = bx;
211  tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
212  tbxp2.grow(IntVect(NGROW,NGROW,0));
213  tbxp11.grow(IntVect(NGROW-1,NGROW-1,NGROW-1));
214 
215  FArrayBox fab_FC(gbx2,1,amrex::The_Async_Arena());
216  FArrayBox fab_BC(gbx2,1,amrex::The_Async_Arena());
217  FArrayBox fab_CF(gbx21,1,amrex::The_Async_Arena());
218  FArrayBox fab_W(tbxp2,1,amrex::The_Async_Arena());
219 
220  auto FC = fab_FC.array();
221  auto W = fab_W.array();
222 
223  //
224  //------------------------------------------------------------------------
225  // Vertically integrate horizontal mass flux divergence.
226  //------------------------------------------------------------------------
227  //
228  //Should really use gbx3uneven
229  //TODO: go over these boxes and compare to other spots where we do the same thing
230  Box gbx1D = gbx1;
231  gbx1D.makeSlab(2,0);
232 
233  // Starting with zero vertical velocity at the bottom, integrate
234  // from the bottom (k=0) to the free-surface (k=N). The w(:,:,N(ng))
235  // contains the vertical velocity at the free-surface, d(zeta)/d(t).
236  // Notice that barotropic mass flux divergence is not used directly.
237  ParallelFor(gbx1D, [=] AMREX_GPU_DEVICE (int i, int j, int )
238  {
239  W(i,j,0) = - (Huon(i+1,j,0)-Huon(i,j,0)) - (Hvom(i,j+1,0)-Hvom(i,j,0));
240 
241  for (int k=1; k<=N; k++) {
242  W(i,j,k) = W(i,j,k-1) - (Huon(i+1,j,k)-Huon(i,j,k)) - (Hvom(i,j+1,k)-Hvom(i,j,k));
243  }
244  });
245 
246  // Starting with zero vertical velocity at the bottom, integrate
247  // from the bottom (k=0) to the free-surface (k=N). The w(:,:,N(ng))
248  // contains the vertical velocity at the free-surface, d(zeta)/d(t).
249  // Notice that barotropic mass flux divergence is not used directly.
250  //
251  ParallelFor(gbx1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
252  {
253  Real wrk_ij = W(i,j,N) / (z_w(i,j,N)+h(i,j,0,0));
254 
255  if(k!=N) {
256  W(i,j,k) -= wrk_ij * (z_w(i,j,k)+h(i,j,0,0));
257  }
258  });
259 
260  ParallelFor(makeSlab(gbx1,2,N), [=] AMREX_GPU_DEVICE (int i, int j, int)
261  {
262  W(i,j,N) = 0.0;
263  });
264 
265  //
266  //-----------------------------------------------------------------------
267  // rhs_t_3d
268  //-----------------------------------------------------------------------
269  //
270  for (int i_comp=0; i_comp < NCONS; i_comp++)
271  {
272  Array4<Real> const& sstore = mf_sstore->array(mfi, i_comp);
273  rhs_t_3d(bx, gbx, mf_cons.array(mfi,i_comp), sstore, Huon, Hvom,
274  Hz, pn, pm, W, FC, nrhs, nnew, N,dt_lev);
275  }
276 
277  } // mfi
278 
279  FillPatch(lev, t_new[lev], mf_cons, cons_new, BdyVars::t);
280 
281  for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
282  {
283  Array4<Real> const& AK = mf_AK.array(mfi);
284  Array4<Real> const& DC = mf_DC.array(mfi);
285 
286  Array4<Real> const& Hzk = mf_Hzk.array(mfi);
287  Array4<Real const> const& Hz = mf_Hz->const_array(mfi);
288 
289  Box bx = mfi.tilebox();
290 
291  // Copy the tilebox
292  Box tbxp1 = bx;
293  Box tbxp11 = bx;
294  Box tbxp2 = bx;
295  Box tbxp21 = bx;
296  //make only gbx be grown to match multifabs
297  tbxp21.grow(IntVect(NGROW,NGROW,NGROW-1));
298  tbxp2.grow(IntVect(NGROW,NGROW,0));
299  tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
300  tbxp11.grow(IntVect(NGROW-1,NGROW-1,NGROW-1));
301 
302  FArrayBox fab_FC(tbxp2,1,amrex::The_Async_Arena());
303  FArrayBox fab_BC(tbxp2,1,amrex::The_Async_Arena());
304  FArrayBox fab_CF(tbxp21,1,amrex::The_Async_Arena());
305  FArrayBox fab_W(tbxp2,1,amrex::The_Async_Arena());
306 
307  auto FC = fab_FC.array();
308  auto BC = fab_BC.array();
309  auto CF = fab_CF.array();
310 
311  for (int i_comp=0; i_comp < NCONS; i_comp++) {
312  vert_visc_3d(bx,0,0,mf_cons.array(mfi,i_comp),Hz,Hzk,
313  AK,mf_Akt->array(mfi,i_comp),BC,DC,FC,CF,nnew,N,dt_lev);
314  }
315  } // MFiter
316 }
#define NCONS
Definition: IndexDefines.H:11
void rhs_t_3d(const amrex::Box &bx, const amrex::Box &gbx, const amrex::Array4< amrex::Real > &t, const amrex::Array4< amrex::Real const > &tempstore, const amrex::Array4< amrex::Real const > &Huon, const amrex::Array4< amrex::Real const > &Hvom, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pn, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &W, const amrex::Array4< amrex::Real > &FC, int nrhs, int nnew, int N, const amrex::Real dt_lev)
Definition: REMORA_rhs_t_3d.cpp:25
void stretch_transform(int lev)
Definition: DepthStretchTransform.H:12
void vert_mean_3d(const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &Dphi_avg1, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &CF, const amrex::Array4< amrex::Real const > &dxlen, const int nnew, const int N)
Definition: REMORA_vert_mean_3d.cpp:10
void vert_visc_3d(const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real > &Hzk, const amrex::Array4< amrex::Real > &AK, const amrex::Array4< amrex::Real > &Akv, const amrex::Array4< amrex::Real > &BC, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real > &CF, const int nnew, const int N, const amrex::Real dt_lev)
Definition: REMORA_vert_visc_3d.cpp:10
void update_massflux_3d(const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real > &phibar, const amrex::Array4< amrex::Real > &Hphi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pm_or_pn, const amrex::Array4< amrex::Real const > &Dphi1, const amrex::Array4< amrex::Real const > &Dphi2, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const int nnew)
Definition: REMORA_update_massflux_3d.cpp:23
@ u
Definition: IndexDefines.H:34
@ v
Definition: IndexDefines.H:35
@ t
Definition: IndexDefines.H:36

◆ advance_3d_ml()

void REMORA::advance_3d_ml ( int  lev,
amrex::Real  dt_lev 
)

3D advance on a single level

7 {
8  // Fill in three ways: 1) interpolate from coarse grid if lev > 0; 2) fill from physical boundaries;
9  // 3) fine-fine fill of ghost cells with FillBoundary call
10  FillPatch(lev, t_new[lev], *cons_new[lev], cons_new, BdyVars::t);
11  FillPatch(lev, t_new[lev], *xvel_new[lev], xvel_new, BdyVars::u);
12  FillPatch(lev, t_new[lev], *yvel_new[lev], yvel_new, BdyVars::v);
13  FillPatch(lev, t_new[lev], *zvel_new[lev], zvel_new, BdyVars::null);
14 
15  FillPatch(lev, t_new[lev], *vec_sstore[lev], GetVecOfPtrs(vec_sstore), BdyVars::t);
16 
17  auto N = Geom(lev).Domain().size()[2]-1; // Number of vertical "levs" aka, NZ
18 
19  advance_3d(lev, *cons_new[lev], *xvel_new[lev], *yvel_new[lev],
20  vec_sstore[lev].get(),
21  vec_ru[lev].get(), vec_rv[lev].get(),
22  vec_DU_avg1[lev], vec_DU_avg2[lev],
23  vec_DV_avg1[lev], vec_DV_avg2[lev],
24  vec_ubar[lev], vec_vbar[lev],
25  vec_Akv[lev], vec_Akt[lev], vec_Hz[lev], vec_Huon[lev], vec_Hvom[lev],
26  vec_z_w[lev], vec_hOfTheConfusingName[lev].get(),
27  vec_pm[lev].get(), vec_pn[lev].get(),
28  N, dt_lev);
29 
30  FillPatch(lev, t_new[lev], *vec_ubar[lev], GetVecOfPtrs(vec_ubar), BdyVars::ubar);
31  FillPatch(lev, t_new[lev], *vec_vbar[lev], GetVecOfPtrs(vec_vbar), BdyVars::vbar);
32  FillPatch(lev, t_new[lev], *vec_sstore[lev], GetVecOfPtrs(vec_sstore), BdyVars::t);
33 
34  // Fill in three ways: 1) interpolate from coarse grid if lev > 0; 2) fill from physical boundaries;
35  // 3) fine-fine fill of ghost cells with FillBoundary call
36  // Note that we need the fine-fine and physical bc's in order to correctly move the particles
37  FillPatch(lev, t_new[lev], *cons_new[lev], cons_new, BdyVars::t);
38  FillPatch(lev, t_new[lev], *xvel_new[lev], xvel_new, BdyVars::u);
39  FillPatch(lev, t_new[lev], *yvel_new[lev], yvel_new, BdyVars::v);
40  FillPatch(lev, t_new[lev], *zvel_new[lev], zvel_new, BdyVars::null);
41 
42 #ifdef REMORA_USE_PARTICLES
43  //***************************************************
44  //Advance particles
45  //***************************************************
46  particleData.advance_particles(lev, dt_lev, xvel_new[lev], yvel_new[lev], zvel_new[lev], vec_z_phys_nd);
47 #endif
48 }
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_sstore
Definition: REMORA.H:291
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Hz
Definition: REMORA.H:200
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Akt
Definition: REMORA.H:216
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Huon
Definition: REMORA.H:202
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_phys_nd
Definition: REMORA.H:240
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Akv
Definition: REMORA.H:214
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_w
Definition: REMORA.H:234
void advance_3d(int lev, amrex::MultiFab &mf_cons, amrex::MultiFab &mf_u, amrex::MultiFab &mf_v, amrex::MultiFab *mf_sstore, amrex::MultiFab *mf_ru, amrex::MultiFab *mf_rv, std::unique_ptr< amrex::MultiFab > &mf_DU_avg1, std::unique_ptr< amrex::MultiFab > &mf_DU_avg2, std::unique_ptr< amrex::MultiFab > &mf_DV_avg1, std::unique_ptr< amrex::MultiFab > &mf_DV_avg2, std::unique_ptr< amrex::MultiFab > &mf_ubar, std::unique_ptr< amrex::MultiFab > &mf_vbar, std::unique_ptr< amrex::MultiFab > &mf_Akv, std::unique_ptr< amrex::MultiFab > &mf_Akt, std::unique_ptr< amrex::MultiFab > &mf_Hz, std::unique_ptr< amrex::MultiFab > &mf_Huon, std::unique_ptr< amrex::MultiFab > &mf_Hvom, std::unique_ptr< amrex::MultiFab > &mf_z_w, amrex::MultiFab const *mf_h, amrex::MultiFab const *mf_pm, amrex::MultiFab const *mf_pn, const int N, const amrex::Real dt_lev)
Definition: REMORA_advance_3d.cpp:10
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Hvom
Definition: REMORA.H:204
@ null
Definition: IndexDefines.H:33

◆ AverageDown()

void REMORA::AverageDown ( )
private

set covered coarse cells to be the average of overlying fine cells

632 {
633  for (int lev = finest_level-1; lev >= 0; --lev)
634  {
635  AverageDownTo(lev);
636  }
637 }
void AverageDownTo(int crse_lev)
Definition: REMORA.cpp:641

◆ AverageDownTo()

void REMORA::AverageDownTo ( int  crse_lev)
private

more flexible version of AverageDown() that lets you average down across multiple levels

642 {
643  average_down(*cons_new[crse_lev+1], *cons_new[crse_lev],
644  0, cons_new[crse_lev]->nComp(), refRatio(crse_lev));
645 
646  Array<MultiFab*,AMREX_SPACEDIM> faces_crse;
647  Array<MultiFab*,AMREX_SPACEDIM> faces_fine;
648  faces_crse[0] = xvel_new[crse_lev];
649  faces_crse[1] = yvel_new[crse_lev];
650  faces_crse[2] = zvel_new[crse_lev];
651 
652  faces_fine[0] = xvel_new[crse_lev+1];
653  faces_fine[1] = yvel_new[crse_lev+1];
654  faces_fine[2] = zvel_new[crse_lev+1];
655 
656  average_down_faces(GetArrOfConstPtrs(faces_fine), faces_crse,
657  refRatio(crse_lev),geom[crse_lev]);
658 }

◆ build_fine_mask()

MultiFab & REMORA::build_fine_mask ( int  lev)

Make mask to zero out covered cells

116 {
117  // Mask for zeroing covered cells
118  AMREX_ASSERT(level > 0);
119 
120  const BoxArray& cba = grids[level-1];
121  const DistributionMapping& cdm = dmap[level-1];
122 
123  // TODO -- we should make a vector of these a member of REMORA class
124  fine_mask.define(cba, cdm, 1, 0, MFInfo());
125  fine_mask.setVal(1.0);
126 
127  BoxArray fba = grids[level];
128  iMultiFab ifine_mask = makeFineMask(cba, cdm, fba, ref_ratio[level-1], 1, 0);
129 
130  const auto fma = fine_mask.arrays();
131  const auto ifma = ifine_mask.arrays();
132  ParallelFor(fine_mask, [=] AMREX_GPU_DEVICE(int bno, int i, int j, int k) noexcept
133  {
134  fma[bno](i,j,k) = ifma[bno](i,j,k);
135  });
136 
137  Gpu::synchronize();
138 
139  return fine_mask;
140 }
amrex::MultiFab fine_mask
Definition: REMORA.H:886

◆ ClearLevel()

void REMORA::ClearLevel ( int  lev)
overridevirtual

Delete level data Overrides the pure virtual function in AmrCore

328 {
329  delete cons_new[lev]; delete xvel_new[lev]; delete yvel_new[lev]; delete zvel_new[lev];
330  delete cons_old[lev]; delete xvel_old[lev]; delete yvel_old[lev]; delete zvel_old[lev];
331 }

◆ ComputeDt()

void REMORA::ComputeDt ( )
private

a wrapper for estTimeStep()

9 {
10  Vector<Real> dt_tmp(finest_level+1);
11 
12  for (int lev = 0; lev <= finest_level; ++lev)
13  {
14  dt_tmp[lev] = estTimeStep(lev);
15  }
16 
17  ParallelDescriptor::ReduceRealMin(&dt_tmp[0], dt_tmp.size());
18 
19  Real dt_0 = dt_tmp[0];
20  int n_factor = 1;
21  for (int lev = 0; lev <= finest_level; ++lev) {
22  dt_tmp[lev] = amrex::min(dt_tmp[lev], change_max*dt[lev]);
23  n_factor *= nsubsteps[lev];
24  dt_0 = amrex::min(dt_0, n_factor*dt_tmp[lev]);
25  }
26 
27  // Limit dt's by the value of stop_time.
28  const Real eps = 1.e-3*dt_0;
29  if (t_new[0] + dt_0 > stop_time - eps) {
30  dt_0 = stop_time - t_new[0];
31  }
32 
33  dt[0] = dt_0;
34  for (int lev = 1; lev <= finest_level; ++lev) {
35  dt[lev] = dt[lev-1] / nsubsteps[lev];
36  }
37 }
amrex::Real stop_time
Definition: REMORA.H:776
static amrex::Real change_max
Definition: REMORA.H:784
amrex::Real estTimeStep(int lev) const
Definition: REMORA_ComputeTimestep.cpp:40

◆ ComputeGhostCells()

AMREX_FORCE_INLINE int REMORA::ComputeGhostCells ( const int &  spatial_order)
inlineprivate
890  {
891  int nGhostCells;
892 
893  switch (spatial_order) {
894  case 2:
895  nGhostCells = 2; // We need this many to compute the eddy viscosity in the ghost cells
896  break;
897  case 3:
898  nGhostCells = 2;
899  break;
900  case 4:
901  nGhostCells = 2;
902  break;
903  case 5:
904  nGhostCells = 3;
905  break;
906  case 6:
907  nGhostCells = 3;
908  break;
909  default:
910  amrex::Error("Must specify spatial order to be 2,3,4,5 or 6");
911  }
912 
913  return nGhostCells;
914  }

◆ coriolis()

void REMORA::coriolis ( const amrex::Box &  xbx,
const amrex::Box &  ybx,
const amrex::Array4< amrex::Real const > &  uold,
const amrex::Array4< amrex::Real const > &  vold,
const amrex::Array4< amrex::Real > &  ru,
const amrex::Array4< amrex::Real > &  rv,
const amrex::Array4< amrex::Real const > &  Hz,
const amrex::Array4< amrex::Real const > &  fomn,
int  nrhs,
int  nr 
)
18 {
19  //
20  //-----------------------------------------------------------------------
21  // Add in Coriolis terms.
22  //-----------------------------------------------------------------------
23  //
24 
25  ParallelFor(xbx,
26  [=] AMREX_GPU_DEVICE (int i, int j, int k)
27  {
28  Real UFx_i = 0.5 * Hz(i ,j,k) * fomn(i ,j,0) * (vold(i ,j,k,nrhs)+vold(i ,j+1,k,nrhs));
29  Real UFx_im1 = 0.5 * Hz(i-1,j,k) * fomn(i-1,j,0) * (vold(i-1,j,k,nrhs)+vold(i-1,j+1,k,nrhs));
30  ru(i,j,k,nr) += 0.5*(UFx_i + UFx_im1);
31  });
32 
33  ParallelFor(ybx,
34  [=] AMREX_GPU_DEVICE (int i, int j, int k)
35  {
36  Real VFe_j = 0.5 * Hz(i,j ,k) * fomn(i,j ,0) * (uold(i,j ,k,nrhs)+uold(i+1,j ,k,nrhs));
37  Real VFe_jm1 = 0.5 * Hz(i,j-1,k) * fomn(i,j-1,0) * (uold(i,j-1,k,nrhs)+uold(i+1,j-1,k,nrhs));
38  rv(i,j,k,nr) -= 0.5*(VFe_j + VFe_jm1);
39  });
40 }

◆ DataLog()

AMREX_FORCE_INLINE std::ostream& REMORA::DataLog ( int  i)
inlineprivate
925  {
926  return *datalog[i];
927  }
amrex::Vector< std::unique_ptr< std::fstream > > datalog
Definition: REMORA.H:967

◆ DataLogName()

const std::string REMORA::DataLogName ( int  i) const
inlineprivatenoexcept

The filename of the ith datalog file.

971 { return datalogname[i]; }
amrex::Vector< std::string > datalogname
Definition: REMORA.H:968

◆ ErrorEst()

void REMORA::ErrorEst ( int  lev,
amrex::TagBoxArray &  tags,
amrex::Real  time,
int  ngrow 
)
overridevirtual

Tag cells for refinement

Function to tag cells for refinement – this overrides the pure virtual function in AmrCore

Parameters
[in]levellevel of refinement (0 is coarsest leve)
[out]tagsarray of tagged cells
[in]timecurrent time
16 {
17  const int clearval = TagBox::CLEAR;
18  const int tagval = TagBox::SET;
19  for (int j=0; j < ref_tags.size(); ++j)
20  {
21  std::unique_ptr<MultiFab> mf;
22 
23  // This allows dynamic refinement based on the value of the scalar
24  if (ref_tags[j].Field() == "scalar")
25  {
26  mf = std::make_unique<MultiFab>(grids[level], dmap[level], 1, 0);
27  MultiFab::Copy(*mf,*cons_new[level],Scalar_comp,0,1,0);
28  }
29 
30  ref_tags[j](tags,mf.get(),clearval,tagval,time,level,geom[level]);
31  }
32 }
#define Scalar_comp
Definition: IndexDefines.H:10
static amrex::Vector< amrex::AMRErrorTag > ref_tags
Definition: REMORA.H:880

◆ estTimeStep()

Real REMORA::estTimeStep ( int  lev) const

compute dt from CFL considerations

41 {
42  BL_PROFILE("REMORA::estTimeStep()");
43 
44  amrex::Real estdt_lowM = 1.e20;
45 
46  auto const dxinv = geom[level].InvCellSizeArray();
47 
48  MultiFab ccvel(grids[level],dmap[level],3,0);
49 
50  average_face_to_cellcenter(ccvel,0,
51  Array<const MultiFab*,3>{xvel_new[level], yvel_new[level], zvel_new[level]});
52 
53  Real estdt_lowM_inv = amrex::ReduceMax(ccvel, 0,
54  [=] AMREX_GPU_HOST_DEVICE (Box const& b,
55  Array4<Real const> const& u) -> Real
56  {
57  Real new_lm_dt = -1.e100;
58  amrex::Loop(b, [=,&new_lm_dt] (int i, int j, int k) noexcept
59  {
60  new_lm_dt = amrex::max(((amrex::Math::abs(u(i,j,k,0)))*dxinv[0]),
61  ((amrex::Math::abs(u(i,j,k,1)))*dxinv[1]),
62  ((amrex::Math::abs(u(i,j,k,2)))*dxinv[2]), new_lm_dt);
63  });
64  return new_lm_dt;
65  });
66 
67  ParallelDescriptor::ReduceRealMax(estdt_lowM_inv);
68  if (estdt_lowM_inv > 0.0_rt)
69  estdt_lowM = cfl / estdt_lowM_inv;;
70 
71  if (verbose) {
72  if (fixed_dt <= 0.0) {
73  amrex::Print() << "Using cfl = " << cfl << std::endl;
74  if (estdt_lowM_inv > 0.0_rt) {
75  amrex::Print() << "Slow dt at level " << level << ": " << estdt_lowM << std::endl;
76  } else {
77  amrex::Print() << "Slow dt at level " << level << ": undefined " << std::endl;
78  }
79  }
80  if (fixed_dt > 0.0) {
81  amrex::Print() << "Based on cfl of 1.0 " << std::endl;
82  if (estdt_lowM_inv > 0.0_rt) {
83  amrex::Print() << "Slow dt at level " << level << " would be: " << estdt_lowM/cfl << std::endl;
84  } else {
85  amrex::Print() << "Slow dt at level " << level << " would be undefined " << std::endl;
86  }
87  amrex::Print() << "Fixed dt at level " << level << " is: " << fixed_dt << std::endl;
88  }
89  }
90 
91  if (fixed_dt > 0.0) {
92  return fixed_dt;
93  } else {
94  return estdt_lowM;
95  }
96 }
static amrex::Real fixed_dt
Definition: REMORA.H:787
static amrex::Real cfl
Definition: REMORA.H:782
static int verbose
Definition: REMORA.H:829

◆ Evolve()

void REMORA::Evolve ( )

Advance solution to final time

143 {
144  Real cur_time = t_new[0];
145 
146  // Take one coarse timestep by calling timeStep -- which recursively calls timeStep
147  // for finer levels (with or without subcycling)
148  for (int step = istep[0]; step < max_step && cur_time < stop_time; ++step)
149  {
150  amrex::Print() << "\nCoarse STEP " << step+1 << " starts ..." << std::endl;
151 
152  ComputeDt();
153 
154  int lev = 0;
155  int iteration = 1;
156 
157  if (max_level == 0) {
158  timeStep(lev, cur_time, iteration);
159  }
160  else {
161  timeStepML(cur_time, iteration);
162  }
163 
164  cur_time += dt[0];
165 
166  amrex::Print() << "Coarse STEP " << step+1 << " ends." << " TIME = " << cur_time
167  << " DT = " << dt[0] << std::endl;
168 
169  if (plot_int_1 > 0 && (step+1) % plot_int_1 == 0) {
170  last_plot_file_step_1 = step+1;
173 #ifdef REMORA_USE_NETCDF
175  WriteNCPlotFile(step);
176 #endif
177  }
178  if (plot_int_2 > 0 && (step+1) % plot_int_2 == 0) {
179  last_plot_file_step_2 = step+1;
182 #ifdef REMORA_USE_NETCDF
184  WriteNCPlotFile(step);
185 #endif
186  }
187 
188  if (check_int > 0 && (step+1) % check_int == 0) {
189  last_check_file_step = step+1;
191  }
192 
193  post_timestep(step, cur_time, dt[0]);
194 
195 #ifdef AMREX_MEM_PROFILING
196  {
197  std::ostringstream ss;
198  ss << "[STEP " << step+1 << "]";
199  MemProfiler::report(ss.str());
200  }
201 #endif
202 
203  if (cur_time >= stop_time - 1.e-6*dt[0]) break;
204  }
205 
206  if (plot_int_1 > 0 && istep[0] > last_plot_file_step_1) {
209 #ifdef REMORA_USE_NETCDF
211  WriteNCPlotFile(istep[0]);
212 #endif
213  }
214  if (plot_int_2 > 0 && istep[0] > last_plot_file_step_2) {
217 #ifdef REMORA_USE_NETCDF
219  WriteNCPlotFile(istep[0]);
220 #endif
221  }
222 
223  if (check_int > 0 && istep[0] > last_check_file_step) {
225  }
226 
227 }
static PlotfileType plotfile_type
Definition: REMORA.H:839
int plot_int_2
Definition: REMORA.H:803
int plot_int_1
Definition: REMORA.H:802
int last_plot_file_step_2
Definition: REMORA.H:766
void post_timestep(int nstep, amrex::Real time, amrex::Real dt_lev)
Definition: REMORA.cpp:231
int max_step
Definition: REMORA.H:775
void WritePlotFile(int which, amrex::Vector< std::string > plot_var_names)
Definition: Plotfile.cpp:99
int last_check_file_step
Definition: REMORA.H:768
void ComputeDt()
Definition: REMORA_ComputeTimestep.cpp:8
int last_plot_file_step_1
Definition: REMORA.H:765
void timeStep(int lev, amrex::Real time, int iteration)
Definition: REMORA_TimeStep.cpp:9
void timeStepML(amrex::Real time, int iteration)
Definition: REMORA_TimeStepML.cpp:9
int check_int
Definition: REMORA.H:807
void WriteCheckpointFile() const
Definition: Checkpoint.cpp:15

Referenced by main().

Here is the caller graph for this function:

◆ fill_from_bdyfiles()

void REMORA::fill_from_bdyfiles ( amrex::MultiFab &  mf_to_fill,
const amrex::Real  time,
const int  bdy_var_type 
)

◆ fill_rhs()

void REMORA::fill_rhs ( amrex::MultiFab &  rhs_mf,
const amrex::MultiFab &  state_mf,
const amrex::Real  time,
const amrex::Geometry &  geom 
)
private

◆ FillCoarsePatch()

void REMORA::FillCoarsePatch ( int  lev,
amrex::Real  time,
amrex::MultiFab *  mf_fine,
amrex::MultiFab *  mf_crse 
)
private

fill an entire multifab by interpolating from the coarser level this comes into play when a new level of refinement appears

177 {
178  BL_PROFILE_VAR("FillCoarsePatch()",FillCoarsePatch);
179  AMREX_ASSERT(lev > 0);
180 
181  int bccomp = 0;
182  int icomp = 0;
183  int ncomp = 1;
184  amrex::Interpolater* mapper = nullptr;
185 
186  Box box_mf = ((*mf_to_fill)[0]).box();
187  if (box_mf.ixType() == IndexType(IntVect(0,0,0)))
188  {
189  bccomp = 0;
190  mapper = &cell_cons_interp;
191  ncomp = NCONS;
192  }
193  else if (box_mf.ixType() == IndexType(IntVect(1,0,0)))
194  {
195  bccomp = BCVars::xvel_bc;
196  mapper = &face_linear_interp;
197  }
198  else if (box_mf.ixType() == IndexType(IntVect(0,1,0)))
199  {
200  bccomp = BCVars::yvel_bc;
201  mapper = &face_linear_interp;
202  }
203  else if (box_mf.ixType() == IndexType(IntVect(0,0,1)))
204  {
205  bccomp = BCVars::zvel_bc;
206  mapper = &face_linear_interp;
207  } else {
208  amrex::Abort("Dont recognize this box type in REMORA_FillPatch");
209  }
210 
211 #if 0
212  TimeInterpolatedData cdata = GetDataAtTime(lev-1, time);
213  TimeInterpolatedData fdata = GetDataAtTime(lev , time);
214  Vector<Real> ctime = {cdata.get_time()};
215 
216  Vector<MultiFab*> cmf = {mf_crse};
217  Vector<Real> ctime = {time};
218 
219  REMORAPhysBCFunct cphysbc(lev-1,geom[lev-1],
221  cdata,
223 #ifdef REMORA_USE_NETCDF
224  ,ic_bc_type,bdy_data_xlo,bdy_data_xhi,
225  bdy_data_ylo,bdy_data_yhi,bdy_time_interval
226 #endif
227  );
228  REMORAPhysBCFunct fphysbc(lev,geom[lev],
230  fdata,
232 #ifdef REMORA_USE_NETCDF
233  ,ic_bc_type,bdy_data_xlo,bdy_data_xhi,
234  bdy_data_ylo,bdy_data_yhi,bdy_time_interval
235 #endif
236  );
237 #endif
238 
239 // amrex::InterpFromCoarseLevel(mf, time, *cmf[0], 0, icomp, ncomp, geom[lev-1], geom[lev],
240 // cphysbc, 0, fphysbc, 0, refRatio(lev-1),
241 // mapper, domain_bcs_type, bccomp);
242  amrex::InterpFromCoarseLevel(*mf_to_fill, time, mf_crse[lev-1], 0, icomp, ncomp, geom[lev-1], geom[lev],
243  null_bc, 0, null_bc, 0, refRatio(lev-1),
244  mapper, domain_bcs_type, bccomp);
245 }
PhysBCFunctNoOp null_bc
Definition: REMORA_FillPatch.cpp:8
Definition: REMORA_PhysBCFunct.H:34
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NCONS > m_bc_extdir_vals
Definition: REMORA.H:760
amrex::Vector< amrex::BCRec > domain_bcs_type
Definition: REMORA.H:753
void FillCoarsePatch(int lev, amrex::Real time, amrex::MultiFab *mf_fine, amrex::MultiFab *mf_crse)
Definition: REMORA_FillPatch.cpp:176
TimeInterpolatedData GetDataAtTime(int lev, amrex::Real time)
Definition: REMORA_FillPatch.cpp:115
amrex::Gpu::DeviceVector< amrex::BCRec > domain_bcs_type_d
Definition: REMORA.H:754
@ zvel_bc
Definition: IndexDefines.H:23
@ yvel_bc
Definition: IndexDefines.H:22
@ xvel_bc
Definition: IndexDefines.H:21
Definition: TimeInterpolatedData.H:8
amrex::Real get_time()
Definition: TimeInterpolatedData.H:21
Here is the call graph for this function:

◆ FillPatch()

void REMORA::FillPatch ( int  lev,
amrex::Real  time,
amrex::MultiFab &  mf_to_be_filled,
amrex::Vector< amrex::MultiFab * > const &  mfs,
const int  bdy_var_type = BdyVars::null 
)
22 {
23  BL_PROFILE_VAR("REMORA::FillPatch()",REMORA_FillPatch);
24  int bccomp;
25  amrex::Interpolater* mapper = nullptr;
26 
27  const int icomp = 0;
28  const int ncomp = mf_to_fill.nComp();
29 
30  Box mf_box(mf_to_fill.boxArray()[0]);
31  if (mf_box.ixType() == IndexType(IntVect(0,0,0)))
32  {
33  bccomp = 0;
34  mapper = &cell_cons_interp;
35  }
36  else if (mf_box.ixType() == IndexType(IntVect(1,0,0)))
37  {
38  bccomp = BCVars::xvel_bc;
39  mapper = &face_linear_interp;
40  }
41  else if (mf_box.ixType() == IndexType(IntVect(0,1,0)))
42  {
43  bccomp = BCVars::yvel_bc;
44  mapper = &face_linear_interp;
45  }
46  else if (mf_box.ixType() == IndexType(IntVect(0,0,1)))
47  {
48  bccomp = BCVars::zvel_bc;
49  mapper = &face_linear_interp;
50  }
51  else
52  {
53  amrex::Abort("Dont recognize this box type in REMORA_FillPatch");
54  }
55 
56  if (lev == 0)
57  {
58  Vector<MultiFab*> fmf = {mfs[lev], mfs[lev]};
59  Vector<Real> ftime = {t_old[lev], t_new[lev]};
60  amrex::FillPatchSingleLevel(mf_to_fill, time, fmf, ftime, icomp, icomp, ncomp,
61  geom[lev], null_bc, bccomp);
62  }
63  else
64  {
65  Vector<MultiFab*> fmf = {mfs[lev], mfs[lev]};
66  Vector<Real> ftime = {t_old[lev], t_new[lev]};
67  Vector<MultiFab*> cmf = {mfs[lev-1], mfs[lev-1]};
68  Vector<Real> ctime = {t_old[lev-1], t_new[lev-1]};
69 
70  amrex::FillPatchTwoLevels(mf_to_fill, time, cmf, ctime, fmf, ftime,
71  0, icomp, ncomp, geom[lev-1], geom[lev],
72  null_bc, bccomp, null_bc, bccomp, refRatio(lev-1),
73  mapper, domain_bcs_type, bccomp);
74  } // lev > 0
75 
76  // ***************************************************************************
77  // Physical bc's at domain boundary
78  // ***************************************************************************
79 
80 #ifdef REMORA_USE_NETCDF
81  // Fill the data which is stored in the boundary data read from netcdf files
82  if ( (solverChoice.ic_bc_type == IC_BC_Type::Real) && (lev==0) &&
83  (bdy_var_type != BdyVars::null) )
84  {
85  fill_from_bdyfiles (mf_to_fill,time,bdy_var_type);
86  }
87 #endif
88 
89  // Enforce physical boundary conditions
90  (*physbcs[lev])(mf_to_fill,0,ncomp,mf_to_fill.nGrowVect(),time,bccomp);
91 
92  // Also enforce free-slip at top boundary (on xvel or yvel)
93  if ( (mf_box.ixType() == IndexType(IntVect(1,0,0))) ||
94  (mf_box.ixType() == IndexType(IntVect(0,1,0))) )
95  {
96  int khi = geom[lev].Domain().bigEnd(2);
97  for (MFIter mfi(mf_to_fill); mfi.isValid(); ++mfi)
98  {
99  Box gbx = mfi.growntilebox(); // Note this is face-centered since vel is
100  gbx.setSmall(2,khi+1);
101  if (gbx.ok()) {
102  Array4<Real> vel_arr = mf_to_fill.array(mfi);
103  ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
104  {
105  vel_arr(i,j,k) = vel_arr(i,j,khi);
106  });
107  }
108  }
109  }
110 }
void fill_from_bdyfiles(amrex::MultiFab &mf_to_fill, const amrex::Real time, const int bdy_var_type)
IC_BC_Type ic_bc_type
Definition: DataStruct.H:208

◆ getAdvFluxReg()

AMREX_FORCE_INLINE amrex::YAFluxRegister* REMORA::getAdvFluxReg ( int  lev)
inlineprivate
918  {
919  return advflux_reg[lev];
920  }

◆ getCPUTime()

amrex::Real REMORA::getCPUTime ( ) const
inlineprivate
941  {
942  int numCores = amrex::ParallelDescriptor::NProcs();
943 #ifdef _OPENMP
944  numCores = numCores * omp_get_max_threads();
945 #endif
946 
947  amrex::Real T =
948  numCores * (amrex::ParallelDescriptor::second() - startCPUTime) +
950 
951  return T;
952  }
static amrex::Real previousCPUTimeUsed
Definition: REMORA.H:937
static amrex::Real startCPUTime
Definition: REMORA.H:936

Referenced by writeJobInfo().

Here is the caller graph for this function:

◆ GetDataAtTime()

TimeInterpolatedData REMORA::GetDataAtTime ( int  lev,
amrex::Real  time 
)
private

utility to copy in data from old and/or new state into another multifab

116 {
117  BL_PROFILE_VAR("GetDataAtTime()",GetDataAtTime);
119 
120 // HACK HACK HACK
121 #if 0
122  const Real teps = (t_new[lev] - t_old[lev]) * 1.e-3;
123 
124  if (time > t_new[lev] - teps && time < t_new[lev] + teps)
125  {
126  for (int i = 0; i < Vars::NumTypes; ++i) {
127  data.add_var(&vars_new[lev][i], data.non_owning);
128  }
129  data.set_time(t_new[lev]);
130  }
131  else if (time > t_old[lev] - teps && time < t_old[lev] + teps)
132  {
133  for (int i = 0; i < Vars::NumTypes; ++i) {
134  data.add_var(&vars_old[lev][i], data.non_owning);
135  }
136  data.set_time(t_old[lev]);
137  }
138  else if (time > t_old[lev] && time < t_new[lev])
139  {
140  // do first order interpolation in time between [t_old[lev], t_new[lev]]
141  // time interpolation includes the ghost cells
142  for (int i = 0; i < Vars::NumTypes; ++i) {
143  MultiFab* mf_tmp = new MultiFab(vars_new[lev][i].boxArray(),
144  vars_new[lev][i].DistributionMap(),
145  vars_new[lev][i].nComp(), vars_new[lev][i].nGrowVect());
146  mf_tmp->setVal(0.0_rt);
147 
148  const Real dt_fraction = (time - t_old[lev]) / (t_new[lev] - t_old[lev]);
149  MultiFab::Saxpy(*mf_tmp, 1.0_rt - dt_fraction, vars_old[lev][i], 0, 0, mf_tmp->nComp(), mf_tmp->nGrowVect());
150  MultiFab::Saxpy(*mf_tmp, dt_fraction, vars_new[lev][i], 0, 0, mf_tmp->nComp(), mf_tmp->nGrowVect());
151 
152  data.add_var(mf_tmp, data.owning);
153  }
154  data.set_time(time);
155  }
156  else
157  {
158  amrex::Error("Requested data at a time outside the interval [t_old, t_new]");
159  }
160 
161  // We need to make sure to fill these before we compute the viscosity
162  for (int i = 0; i < Vars::NumTypes; ++i) {
163  data.get_var(Vars::xvel).FillBoundary(geom[lev].periodicity());
164  data.get_var(Vars::yvel).FillBoundary(geom[lev].periodicity());
165  data.get_var(Vars::zvel).FillBoundary(geom[lev].periodicity());
166  data.get_var(Vars::cons).FillBoundary(geom[lev].periodicity());
167  }
168 #endif
169  return data;
170 }
@ NumTypes
Definition: IndexDefines.H:24
void set_time(amrex::Real time)
Definition: TimeInterpolatedData.H:17
const int non_owning
Definition: TimeInterpolatedData.H:50
void add_var(amrex::MultiFab *var_data, int own_data)
Definition: TimeInterpolatedData.H:23
amrex::MultiFab & get_var(int var_idx)
Definition: TimeInterpolatedData.H:28
const int owning
Definition: TimeInterpolatedData.H:49
Here is the call graph for this function:

◆ GotoNextLine()

void REMORA::GotoNextLine ( std::istream &  is)
staticprivate
9 {
10  constexpr std::streamsize bl_ignore_max { 100000 };
11  is.ignore(bl_ignore_max, '\n');
12 }

◆ init1DArrays()

void REMORA::init1DArrays ( )
private

◆ init_bcs()

void REMORA::init_bcs ( )
private
10 {
11  auto f = [this] (std::string const& bcid, Orientation ori)
12  {
13  // These are simply defaults for Dirichlet faces -- they should be over-written below
17 
18  m_bc_extdir_vals[BCVars::xvel_bc][ori] = 0.0; // default
21 
22  ParmParse pp(bcid);
23  std::string bc_type_in = "null";
24  pp.query("type", bc_type_in);
25  std::string bc_type = amrex::toLower(bc_type_in);
26 
27  if (bc_type == "symmetry")
28  {
30  domain_bc_type[ori] = "Symmetry";
31  }
32  else if (bc_type == "outflow")
33  {
35  domain_bc_type[ori] = "Outflow";
36  }
37  else if (bc_type == "inflow")
38  {
40  domain_bc_type[ori] = "Inflow";
41 
42  std::vector<Real> v;
43  pp.getarr("velocity", v, 0, AMREX_SPACEDIM);
47 
48  Real scalar_in = 0.;
49  if (pp.query("scalar", scalar_in))
50  m_bc_extdir_vals[BCVars::Scalar_bc_comp][ori] = scalar_in;
51  }
52  else if (bc_type == "noslipwall")
53  {
55  domain_bc_type[ori] = "NoSlipWall";
56 
57  std::vector<Real> v;
58 
59  // The values of m_bc_extdir_vals default to 0.
60  // But if we find "velocity" in the inputs file, use those values instead.
61  if (pp.queryarr("velocity", v, 0, AMREX_SPACEDIM))
62  {
63  v[ori.coordDir()] = 0.0;
67  }
68  }
69  else if (bc_type == "slipwall")
70  {
72  domain_bc_type[ori] = "SlipWall";
73  }
74  else
75  {
77  }
78 
79  if (geom[0].isPeriodic(ori.coordDir()))
80  {
81  domain_bc_type[ori] = "Periodic";
83  {
85  } else {
86  amrex::Abort("Wrong BC type for periodic boundary");
87  }
88  }
89 
91  {
92  amrex::Print() << "BC Type specified for face " << bcid << " is " << bc_type_in << std::endl;
93  amrex::Abort("This BC type is unknown");
94  }
95 
96  if ((bcid == "xlo" || bcid == "xhi" ||
97  bcid == "ylo" || bcid == "yhi") &&
100  {
101  amrex::Abort("BC type must be outflow in x and y when reading BCs from file");
102  }
103  };
104 
105  f("xlo", Orientation(Direction::x,Orientation::low));
106  f("xhi", Orientation(Direction::x,Orientation::high));
107  f("ylo", Orientation(Direction::y,Orientation::low));
108  f("yhi", Orientation(Direction::y,Orientation::high));
109  f("zlo", Orientation(Direction::z,Orientation::low));
110  f("zhi", Orientation(Direction::z,Orientation::high));
111 
112  // *****************************************************************************
113  //
114  // Here we translate the physical boundary conditions -- one type per face --
115  // into logical boundary conditions for each velocity component
116  //
117  // *****************************************************************************
118  {
119  domain_bcs_type.resize(AMREX_SPACEDIM+NCONS);
120  domain_bcs_type_d.resize(AMREX_SPACEDIM+NCONS);
121 
122  for (OrientationIter oit; oit; ++oit) {
123  Orientation ori = oit();
124  int dir = ori.coordDir();
125  Orientation::Side side = ori.faceDir();
126  auto const bct = phys_bc_type[ori];
127  if ( bct == REMORA_BC::symmetry )
128  {
129  if (side == Orientation::low) {
130  for (int i = 0; i < AMREX_SPACEDIM; i++)
133  } else {
134  for (int i = 0; i < AMREX_SPACEDIM; i++)
137  }
138  }
139  else if (bct == REMORA_BC::outflow)
140  {
141  if (side == Orientation::low) {
142  for (int i = 0; i < AMREX_SPACEDIM; i++)
144  } else {
145  for (int i = 0; i < AMREX_SPACEDIM; i++)
147  }
148  }
149  else if (bct == REMORA_BC::inflow)
150  {
151  if (side == Orientation::low) {
152  for (int i = 0; i < AMREX_SPACEDIM; i++) {
154  }
155  } else {
156  for (int i = 0; i < AMREX_SPACEDIM; i++) {
158  }
159  }
160  }
161  else if (bct == REMORA_BC::no_slip_wall)
162  {
163  if (side == Orientation::low) {
164  for (int i = 0; i < AMREX_SPACEDIM; i++)
166  } else {
167  for (int i = 0; i < AMREX_SPACEDIM; i++)
169  }
170  }
171  else if (bct == REMORA_BC::slip_wall)
172  {
173  if (side == Orientation::low) {
174  for (int i = 0; i < AMREX_SPACEDIM; i++)
176  // Only normal direction has ext_dir
178 
179  } else {
180  for (int i = 0; i < AMREX_SPACEDIM; i++)
182  // Only normal direction has ext_dir
184  }
185  }
186  else if (bct == REMORA_BC::periodic)
187  {
188  if (side == Orientation::low) {
189  for (int i = 0; i < AMREX_SPACEDIM; i++)
191  } else {
192  for (int i = 0; i < AMREX_SPACEDIM; i++)
194  }
195  }
196  }
197  }
198 
199  // *****************************************************************************
200  //
201  // Here we translate the physical boundary conditions -- one type per face --
202  // into logical boundary conditions for each cell-centered variable
203  //
204  // *****************************************************************************
205  {
206  for (OrientationIter oit; oit; ++oit) {
207  Orientation ori = oit();
208  int dir = ori.coordDir();
209  Orientation::Side side = ori.faceDir();
210  auto const bct = phys_bc_type[ori];
211  if ( bct == REMORA_BC::symmetry )
212  {
213  if (side == Orientation::low) {
214  for (int i = 0; i < NCONS; i++)
216  } else {
217  for (int i = 0; i < NCONS; i++)
219  }
220  }
221  else if ( bct == REMORA_BC::outflow )
222  {
223  if (side == Orientation::low) {
224  for (int i = 0; i < NCONS; i++)
226  } else {
227  for (int i = 0; i < NCONS; i++)
229  }
230  }
231  else if ( bct == REMORA_BC::no_slip_wall)
232  {
233  if (side == Orientation::low) {
234  for (int i = 0; i < NCONS; i++)
236  } else {
237  for (int i = 0; i < NCONS; i++)
239  }
240  }
241  else if (bct == REMORA_BC::slip_wall)
242  {
243  if (side == Orientation::low) {
244  for (int i = 0; i < NCONS; i++)
246  } else {
247  for (int i = 0; i < NCONS; i++)
249  }
250  }
251  else if (bct == REMORA_BC::inflow)
252  {
253  if (side == Orientation::low) {
254  for (int i = 0; i < NCONS; i++) {
256  }
257  } else {
258  for (int i = 0; i < NCONS; i++) {
260  }
261  }
262  }
263  else if (bct == REMORA_BC::periodic)
264  {
265  if (side == Orientation::low) {
266  for (int i = 0; i < NCONS; i++)
268  } else {
269  for (int i = 0; i < NCONS; i++)
271  }
272  }
273  }
274  }
275 
276 #ifdef AMREX_USE_GPU
277  Gpu::htod_memcpy
278  (domain_bcs_type_d.data(), domain_bcs_type.data(),
279  sizeof(amrex::BCRec)*(NCONS+AMREX_SPACEDIM));
280 #else
281  std::memcpy
282  (domain_bcs_type_d.data(), domain_bcs_type.data(),
283  sizeof(amrex::BCRec)*(NCONS+AMREX_SPACEDIM));
284 #endif
285 }
amrex::Array< std::string, 2 *AMREX_SPACEDIM > domain_bc_type
Definition: REMORA.H:757
amrex::GpuArray< REMORA_BC, AMREX_SPACEDIM *2 > phys_bc_type
Definition: REMORA.H:763
@ Temp_bc_comp
Definition: IndexDefines.H:18
@ Scalar_bc_comp
Definition: IndexDefines.H:20
@ cons_bc
Definition: IndexDefines.H:17
@ Salt_bc_comp
Definition: IndexDefines.H:19
@ int_dir
Definition: IndexDefines.H:55
@ reflect_odd
Definition: IndexDefines.H:54
@ ext_dir
Definition: IndexDefines.H:58
@ reflect_even
Definition: IndexDefines.H:56
@ foextrap
Definition: IndexDefines.H:57

◆ init_beta_plane_coriolis()

void REMORA::init_beta_plane_coriolis ( int  lev)
55 {
56  std::unique_ptr<MultiFab>& mf_fcor = vec_fcor[lev];
57  auto geomdata = Geom(lev).data();
58 
59 #ifdef _OPENMP
60 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
61 #endif
62  for (MFIter mfi(*cons_new[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi)
63  {
64  auto fcor_arr = (mf_fcor)->array(mfi);
65  Real coriolis_f0 = solverChoice.coriolis_f0;
66  Real coriolis_beta = solverChoice.coriolis_beta;
67  Real Esize = geomdata.ProbHi()[1] - geomdata.ProbLo()[1];
68  Real prob_lo = geomdata.ProbLo()[1];
69  Real dx = geomdata.CellSize()[1];
70 
71  ParallelFor(Box(fcor_arr), [=] AMREX_GPU_DEVICE (int i, int j, int )
72  {
73  Real y = prob_lo + (j + 0.5) * dx;
74  fcor_arr(i,j,0) = coriolis_f0 + coriolis_beta * (y - 0.5 * Esize);
75  });
76  } //mfi
77 
78  vec_fcor[lev]->FillBoundary(geom[lev].periodicity());
79 }
amrex::Real coriolis_beta
Definition: DataStruct.H:231
amrex::Real coriolis_f0
Definition: DataStruct.H:230

◆ init_custom()

void REMORA::init_custom ( int  lev)
private
14 {
15  std::unique_ptr<MultiFab>& mf_z_w = vec_z_w[lev];
16  std::unique_ptr<MultiFab>& mf_z_r = vec_z_r[lev];
17  std::unique_ptr<MultiFab>& mf_Hz = vec_Hz[lev];
18  std::unique_ptr<MultiFab>& mf_h = vec_hOfTheConfusingName[lev];
19  std::unique_ptr<MultiFab>& mf_Zt_avg1 = vec_Zt_avg1[lev];
20 
21 #ifdef _OPENMP
22 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
23 #endif
24  for (MFIter mfi(*cons_new[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi)
25  {
26  const Box &bx = mfi.tilebox();
27  const auto &cons_arr = cons_new[lev]->array(mfi);
28  const auto &xvel_arr = xvel_new[lev]->array(mfi);
29  const auto &yvel_arr = yvel_new[lev]->array(mfi);
30  const auto &zvel_arr = zvel_new[lev]->array(mfi);
31 
32  Array4<const Real> const& z_w_arr = (mf_z_w)->array(mfi);
33  Array4<const Real> const& z_r_arr = (mf_z_r)->array(mfi);
34  Array4<const Real> const& Hz_arr = (mf_Hz)->array(mfi);
35  Array4<const Real> const& h_arr = (mf_h)->array(mfi);
36  Array4<const Real> const& Zt_avg1_arr = mf_Zt_avg1->const_array(mfi);
37 
38  init_custom_prob(bx, cons_arr, xvel_arr, yvel_arr, zvel_arr,
39  z_w_arr, z_r_arr, Hz_arr, h_arr, Zt_avg1_arr, geom[lev].data(),
40  solverChoice);
41 
42  } //mfi
43 
44  // Initialize the "pm" and "pn" arrays
45  const auto dxi = Geom(lev).InvCellSize();
46  vec_pm[lev]->setVal(dxi[0]); vec_pm[lev]->FillBoundary(geom[lev].periodicity());
47  vec_pn[lev]->setVal(dxi[1]); vec_pn[lev]->FillBoundary(geom[lev].periodicity());
48 
49  set_2darrays(lev);
50 
51 }
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_r
Definition: REMORA.H:231
void set_2darrays(int lev)
Definition: REMORA_init.cpp:82
void init_custom_prob(const amrex::Box &bx, amrex::Array4< amrex::Real > const &state, amrex::Array4< amrex::Real > const &x_vel, amrex::Array4< amrex::Real > const &y_vel, amrex::Array4< amrex::Real > const &z_vel, amrex::Array4< amrex::Real const > const &z_w, amrex::Array4< amrex::Real const > const &z_r, amrex::Array4< amrex::Real const > const &Hz, amrex::Array4< amrex::Real const > const &h, amrex::Array4< amrex::Real const > const &Zt_avg1, amrex::GeometryData const &geomdata, SolverChoice const &m_solverChoice)
Here is the call graph for this function:

◆ init_only()

void REMORA::init_only ( int  lev,
amrex::Real  time 
)

Init (NOT restart or regrid)

448 {
449  t_new[lev] = time;
450  t_old[lev] = time - 1.e200;
451 
452  cons_new[lev]->setVal(0.0);
453  xvel_new[lev]->setVal(0.0);
454  yvel_new[lev]->setVal(0.0);
455  zvel_new[lev]->setVal(0.0);
456 
458  {
459  init_custom(lev);
460 #ifdef REMORA_USE_NETCDF
461  } else if (solverChoice.ic_bc_type == IC_BC_Type::Real) {
462 
463  amrex::Print() << "Calling init_data_from_netcdf " << std::endl;
464  init_data_from_netcdf(lev);
465  amrex::Print() << "Initial data loaded from netcdf file \n " << std::endl;
466 
467  amrex::Print() << "Calling init_bdry_from_netcdf " << std::endl;
468  init_bdry_from_netcdf();
469  amrex::Print() << "Boundary data loaded from netcdf file \n " << std::endl;
470 #endif
471  } else {
472  Abort("Need to specify ic_bc_type");
473  }
474 
475  // Ensure that the face-based data are the same on both sides of a periodic domain.
476  // The data associated with the lower grid ID is considered the correct value.
477  xvel_new[lev]->OverrideSync(geom[lev].periodicity());
478  yvel_new[lev]->OverrideSync(geom[lev].periodicity());
479  zvel_new[lev]->OverrideSync(geom[lev].periodicity());
480 }
void init_custom(int lev)
Definition: REMORA_init.cpp:13

◆ init_stuff()

void REMORA::init_stuff ( int  lev,
const amrex::BoxArray &  ba,
const amrex::DistributionMapping &  dm 
)
private
192 {
193  // ********************************************************************************************
194  // Initialize the boundary conditions
195  // ********************************************************************************************
196  physbcs[lev] = std::make_unique<REMORAPhysBCFunct> (lev, geom[lev], domain_bcs_type, domain_bcs_type_d,
198 
199  BoxList bl2d = ba.boxList();
200  for (auto& b : bl2d) {
201  b.setRange(2,0);
202  }
203  BoxArray ba2d(std::move(bl2d));
204 
205  BoxList bl1d = ba.boxList();
206  for (auto& b : bl1d) {
207  b.setRange(0,0);
208  b.setRange(1,0);
209  }
210  BoxArray ba1d(std::move(bl1d));
211 
212  // Map factors
213  mapfac_m[lev].reset(new MultiFab(ba2d,dm,1,0));
214  mapfac_u[lev].reset(new MultiFab(convert(ba2d,IntVect(1,0,0)),dm,1,0));
215  mapfac_v[lev].reset(new MultiFab(convert(ba2d,IntVect(0,1,0)),dm,1,0));
216  mapfac_m[lev]->setVal(1.);
217  mapfac_u[lev]->setVal(1.);
218  mapfac_v[lev]->setVal(1.);
219 
220  BoxArray ba_nd(ba);
221  ba_nd.surroundingNodes();
222  BoxArray ba_w(ba);
223  ba_w.surroundingNodes(2);
224 
225  vec_z_phys_nd[lev].reset (new MultiFab(ba_nd,dm,1,IntVect(NGROW,NGROW,0))); // z at psi points (nodes) MIGHT NEED NGROW+1
226 
227  vec_hOfTheConfusingName[lev].reset(new MultiFab(ba2d ,dm,2,IntVect(NGROW+1,NGROW+1,0))); //2d, depth (double check if negative)
228  vec_Zt_avg1[lev].reset (new MultiFab(ba2d ,dm,1,IntVect(NGROW+1,NGROW+1,0))); //2d, average of the free surface (zeta)
229 
230  vec_x_r[lev].reset (new MultiFab(ba2d,dm,1,IntVect(NGROW+1,NGROW+1,0))); // x at r points (cell center)
231  vec_y_r[lev].reset (new MultiFab(ba2d,dm,1,IntVect(NGROW+1,NGROW+1,0))); // y at r points (cell center)
232 
233  vec_s_r[lev].reset (new MultiFab(ba1d,dm,1,IntVect( 0, 0,0))); // scaled vertical coordinate [0,1] , transforms to z
234 
235  vec_z_w[lev].reset (new MultiFab(ba_w,dm,1,IntVect(NGROW+1,NGROW+1,0))); // z at w points (cell faces)
236  vec_z_r[lev].reset (new MultiFab(ba ,dm,1,IntVect(NGROW+1,NGROW+1,0))); // z at r points (cell center)
237  vec_Hz[lev].reset (new MultiFab(ba ,dm,1,IntVect(NGROW+1,NGROW+1,NGROW+1))); // like in ROMS, thickness of cell in z
238 
239  vec_Huon[lev].reset (new MultiFab(convert(ba,IntVect(1,0,0)),dm,1,IntVect(NGROW,NGROW,0))); // mass flux for u component
240  vec_Hvom[lev].reset (new MultiFab(convert(ba,IntVect(0,1,0)),dm,1,IntVect(NGROW,NGROW,0))); // mass flux for v component
241 
242  vec_Akv[lev].reset (new MultiFab(ba ,dm,1,IntVect(NGROW,NGROW,0))); // vertical mixing coefficient (.in)
243  vec_Akt[lev].reset (new MultiFab(ba ,dm,NCONS,IntVect(NGROW,NGROW,0))); // vertical mixing coefficient (.in)
244  vec_visc3d_r[lev].reset (new MultiFab(ba ,dm,1,IntVect(NGROW,NGROW,0))); // not used
245 
246 
247  // check dimensionality
248  vec_visc2_p[lev].reset(new MultiFab(ba,dm,1,IntVect(NGROW,NGROW,0))); // harmonic viscosity at psi points -- difference to 3d?
249  vec_visc2_r[lev].reset(new MultiFab(ba,dm,1,IntVect(NGROW,NGROW,0))); // harmonic viscosity at rho points
250  vec_diff2[lev].reset(new MultiFab(ba,dm,NCONS,IntVect(NGROW,NGROW,0))); // harmonic diffusivity temperature/salt
251 
252  vec_ru[lev].reset(new MultiFab(convert(ba,IntVect(1,0,0)),dm,2,IntVect(NGROW,NGROW,NGROW))); // RHS u (incl horizontal and vertical advection)
253  vec_rv[lev].reset(new MultiFab(convert(ba,IntVect(0,1,0)),dm,2,IntVect(NGROW,NGROW,NGROW))); // RHS v
254 
255  //2d, (incl advection terms and surface/bottom stresses, integral over the whole columnn, k=0)
256  vec_rufrc[lev].reset(new MultiFab(convert(ba2d,IntVect(1,0,0)),dm,2,IntVect(NGROW,NGROW,0)));
257  vec_rvfrc[lev].reset(new MultiFab(convert(ba2d,IntVect(0,1,0)),dm,2,IntVect(NGROW,NGROW,0))); //2d, same as above but v
258 
259  vec_sustr[lev].reset(new MultiFab(convert(ba2d,IntVect(1,0,0)),dm,1,IntVect(NGROW,NGROW,0))); //2d, surface stress
260  vec_svstr[lev].reset(new MultiFab(convert(ba2d,IntVect(0,1,0)),dm,1,IntVect(NGROW,NGROW,0))); //2d
261 
262  //2d, linear drag coefficient [m/s], defined at rho, somehow related to rdrg
263  vec_rdrag[lev].reset(new MultiFab(ba2d,dm,1,IntVect(NGROW,NGROW,0)));
264 
265  vec_bustr[lev].reset(new MultiFab(convert(ba2d,IntVect(1,0,0)),dm,1,IntVect(NGROW,NGROW,0))); //2d, bottom stress
266  vec_bvstr[lev].reset(new MultiFab(convert(ba2d,IntVect(0,1,0)),dm,1,IntVect(NGROW,NGROW,0)));
267 
268  //all 2d -- all associated with the 2D advance
269  //2d DU: sum(height[incl free surface?] * u)
270  vec_DU_avg1[lev].reset(new MultiFab(convert(ba2d,IntVect(1,0,0)),dm,1,IntVect(NGROW,NGROW,0)));
271 
272  //2d like above, but correct(or)?
273  vec_DU_avg2[lev].reset(new MultiFab(convert(ba2d,IntVect(1,0,0)),dm,1,IntVect(NGROW,NGROW,0)));
274 
275  vec_DV_avg1[lev].reset(new MultiFab(convert(ba2d,IntVect(0,1,0)),dm,1,IntVect(NGROW,NGROW,0)));
276  vec_DV_avg2[lev].reset(new MultiFab(convert(ba2d,IntVect(0,1,0)),dm,1,IntVect(NGROW,NGROW,0)));
277 
278  vec_rubar[lev].reset(new MultiFab(convert(ba2d,IntVect(1,0,0)),dm,4,IntVect(NGROW,NGROW,0))); // 2d RHS ubar
279  vec_rvbar[lev].reset(new MultiFab(convert(ba2d,IntVect(0,1,0)),dm,4,IntVect(NGROW,NGROW,0)));
280  vec_rzeta[lev].reset(new MultiFab(ba2d,dm,4,IntVect(NGROW,NGROW,0))); // 2d RHS zeta
281 
282  // starts off kind of like a depth-averaged u, but exists at more points and more timesteps (b/c fast 2D update) than full u
283  vec_ubar[lev].reset(new MultiFab(convert(ba2d,IntVect(1,0,0)),dm,3,IntVect(NGROW,NGROW,0)));
284  vec_vbar[lev].reset(new MultiFab(convert(ba2d,IntVect(0,1,0)),dm,3,IntVect(NGROW,NGROW,0)));
285  vec_zeta[lev].reset(new MultiFab(ba2d,dm,3,IntVect(NGROW+1,NGROW+1,0))); // 2d free surface
286 
287  vec_pm[lev].reset(new MultiFab(ba2d,dm,1,IntVect(NGROW+1,NGROW+2,0)));
288  vec_pn[lev].reset(new MultiFab(ba2d,dm,1,IntVect(NGROW+2,NGROW+1,0)));
289  vec_fcor[lev].reset(new MultiFab(ba2d,dm,1,IntVect(NGROW+1,NGROW+1,0)));
290 
291  // tempstore, saltstore, etc
292  vec_sstore[lev].reset(new MultiFab(ba,dm,NCONS,IntVect(NGROW,NGROW,0)));
293 
294  vec_rhoS[lev].reset(new MultiFab(ba,dm,1,IntVect(NGROW,NGROW,0)));
295  vec_rhoA[lev].reset(new MultiFab(ba,dm,1,IntVect(NGROW,NGROW,0)));
296 
297  set_bathymetry(lev);
298  stretch_transform(lev);
299  set_vmix(lev);
300  set_hmixcoef(lev);
301  set_coriolis(lev);
302  set_weights(lev);
303 
304  //consider tracking ru and rv indexes more specifically or more similarly to indx
305  vec_ru[lev]->setVal(0.0_rt);
306  vec_rv[lev]->setVal(0.0_rt);
307 
308  vec_DU_avg1[lev]->setVal(0.0_rt);
309  vec_DU_avg2[lev]->setVal(0.0_rt);
310  vec_DV_avg1[lev]->setVal(0.0_rt);
311  vec_DV_avg2[lev]->setVal(0.0_rt);
312  vec_rubar[lev]->setVal(0.0_rt);
313  vec_rvbar[lev]->setVal(0.0_rt);
314  vec_rzeta[lev]->setVal(0.0_rt);
315 
316  vec_ubar[lev]->setVal(0.0_rt);
317  vec_vbar[lev]->setVal(0.0_rt);
318  vec_zeta[lev]->setVal(0.0_rt);
319 
320  // Set initial linear drag coefficient
321  vec_rdrag[lev]->setVal(solverChoice.rdrag);
322 }
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_sustr
Definition: REMORA.H:246
void set_coriolis(int lev)
Definition: REMORA.cpp:396
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_x_r
Definition: REMORA.H:225
amrex::Vector< std::unique_ptr< amrex::MultiFab > > mapfac_u
Definition: REMORA.H:742
amrex::Vector< std::unique_ptr< amrex::MultiFab > > mapfac_m
Definition: REMORA.H:741
void set_vmix(int lev)
Definition: REMORA.cpp:418
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_svstr
Definition: REMORA.H:249
void set_bathymetry(int lev)
Definition: REMORA.cpp:372
amrex::Vector< std::unique_ptr< amrex::MultiFab > > mapfac_v
Definition: REMORA.H:743
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_visc3d_r
Definition: REMORA.H:293
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_y_r
Definition: REMORA.H:228
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_bustr
Definition: REMORA.H:255
void set_hmixcoef(int lev)
Definition: REMORA.cpp:427
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_bvstr
Definition: REMORA.H:258
void set_weights(int lev)
Definition: REMORA_set_weights.cpp:10
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rdrag
Definition: REMORA.H:252
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_s_r
Definition: REMORA.H:237
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_diff2
Definition: REMORA.H:222
amrex::Real rdrag
Definition: DataStruct.H:219

◆ InitData()

void REMORA::InitData ( )

Initialize multilevel data

261 {
262  // Initialize the start time for our CPU-time tracker
263  startCPUTime = ParallelDescriptor::second();
264 
265  // Map the words in the inputs file to BC types, then translate
266  // those types into what they mean for each variable
267  init_bcs();
268 
272 
273  if (restart_chkfile == "") {
274  // start simulation from the beginning
275 
276  const Real time = 0.0;
277  InitFromScratch(time);
278 
279  for (int lev = 0; lev <= finest_level; lev++)
280  init_only(lev, time);
281 
283  AverageDown();
284  }
285 
286 #ifdef REMORA_USE_PARTICLES
287  particleData.init_particles((ParGDBBase*)GetParGDB(),vec_z_phys_nd);
288 #endif
289 
290  } else { // Restart from a checkpoint
291 
292  restart();
293 
294  }
295 
296  // Initialize flux registers (whether we start from scratch or restart)
298  advflux_reg[0] = nullptr;
299  for (int lev = 1; lev <= finest_level; lev++)
300  {
301  advflux_reg[lev] = new YAFluxRegister(grids[lev], grids[lev-1],
302  dmap[lev], dmap[lev-1],
303  geom[lev], geom[lev-1],
304  ref_ratio[lev-1], lev, NCONS);
305  }
306  }
307 
308  // Fill ghost cells/faces
309  for (int lev = 0; lev <= finest_level; ++lev)
310  {
311  FillPatch(lev, t_new[lev], *cons_new[lev], cons_new, BdyVars::t);
312  FillPatch(lev, t_new[lev], *xvel_new[lev], xvel_new, BdyVars::u);
313  FillPatch(lev, t_new[lev], *yvel_new[lev], yvel_new, BdyVars::v);
314  FillPatch(lev, t_new[lev], *zvel_new[lev], zvel_new, BdyVars::null);
315 
316  //
317  // Copy from new into old just in case
318  //
319  int ngs = cons_new[lev]->nGrow();
320  int ngvel = xvel_new[lev]->nGrow();
321  MultiFab::Copy(*cons_old[lev],*cons_new[lev],0,0,NCONS,ngs);
322  MultiFab::Copy(*xvel_old[lev],*xvel_new[lev],0,0,1,ngvel);
323  MultiFab::Copy(*yvel_old[lev],*yvel_new[lev],0,0,1,ngvel);
324  MultiFab::Copy(*zvel_old[lev],*zvel_new[lev],0,0,1,IntVect(ngvel,ngvel,0));
325  } // lev
326  if (restart_chkfile == "" && check_int > 0)
327  {
330  }
331 
332  if ( (restart_chkfile == "") ||
334  {
335  if (plot_int_1 > 0)
336  {
339 #ifdef REMORA_USE_NETCDF
341  int step0 = 0;
342  WriteNCPlotFile(step0);
343  }
344 #endif
346  }
347  if (plot_int_2 > 0)
348  {
351  }
352  }
353 
356  }
357 
358  ComputeDt();
359 
360 }
void init_bcs()
Definition: REMORA_init_bcs.cpp:9
static int sum_interval
Definition: REMORA.H:835
void init_only(int lev, amrex::Real time)
Definition: REMORA.cpp:447
void sum_integrated_quantities(amrex::Real time)
Definition: REMORA_SumIQ.cpp:9
int plot_file_on_restart
Definition: REMORA.H:769
bool is_it_time_for_action(int nstep, amrex::Real time, amrex::Real dt, int action_interval, amrex::Real action_per)
Definition: REMORA_SumIQ.cpp:143
void AverageDown()
Definition: REMORA.cpp:631
std::string restart_chkfile
Definition: REMORA.H:779
static amrex::Real sum_per
Definition: REMORA.H:836
void restart()
Definition: REMORA.cpp:363
CouplingType coupling_type
Definition: DataStruct.H:205

Referenced by main().

Here is the caller graph for this function:

◆ initHSE()

void REMORA::initHSE ( )
private

Initialize HSE.

◆ InitializeFromFile()

void REMORA::InitializeFromFile ( )
private

◆ InitializeLevelFromData()

void REMORA::InitializeLevelFromData ( int  lev,
const amrex::MultiFab &  initial_data 
)
private

◆ initRayleigh()

void REMORA::initRayleigh ( )
private

Initialize Rayleigh damping profiles.

◆ is_it_time_for_action()

bool REMORA::is_it_time_for_action ( int  nstep,
amrex::Real  time,
amrex::Real  dt,
int  action_interval,
amrex::Real  action_per 
)
144 {
145  bool int_test = (action_interval > 0 && nstep % action_interval == 0);
146 
147  bool per_test = false;
148  if (action_per > 0.0) {
149  const int num_per_old = static_cast<int>(amrex::Math::floor((time - dtlev) / action_per));
150  const int num_per_new = static_cast<int>(amrex::Math::floor((time) / action_per));
151 
152  if (num_per_old != num_per_new) {
153  per_test = true;
154  }
155  }
156 
157  return int_test || per_test;
158 }

◆ MakeNewLevelFromCoarse()

void REMORA::MakeNewLevelFromCoarse ( int  lev,
amrex::Real  time,
const amrex::BoxArray &  ba,
const amrex::DistributionMapping &  dm 
)
overridevirtual

Make a new level using provided BoxArray and DistributionMapping and fill with interpolated coarse level data. Overrides the pure virtual function in AmrCore

20 {
21  cons_new[lev]->define(ba, dm, NCONS, cons_new[lev-1]->nGrowVect());
22  cons_old[lev]->define(ba, dm, NCONS, cons_new[lev-1]->nGrowVect());
23 
24  xvel_new[lev]->define(convert(ba, IntVect(1,0,0)), dm, 1, xvel_new[lev-1]->nGrowVect());
25  xvel_old[lev]->define(convert(ba, IntVect(1,0,0)), dm, 1, xvel_new[lev-1]->nGrowVect());
26 
27  yvel_new[lev]->define(convert(ba, IntVect(0,1,0)), dm, 1, yvel_new[lev-1]->nGrowVect());
28  yvel_old[lev]->define(convert(ba, IntVect(0,1,0)), dm, 1, yvel_new[lev-1]->nGrowVect());
29 
30  zvel_new[lev]->define(convert(ba, IntVect(0,0,1)), dm, 1, zvel_new[lev-1]->nGrowVect());
31  zvel_old[lev]->define(convert(ba, IntVect(0,0,1)), dm, 1, zvel_new[lev-1]->nGrowVect());
32 
33  resize_stuff(lev);
34  init_stuff(lev, ba, dm);
35 
36  t_new[lev] = time;
37  t_old[lev] = time - 1.e200;
38 
39  FillCoarsePatch(lev, time, cons_new[lev], cons_new[lev-1]);
40  FillCoarsePatch(lev, time, xvel_new[lev], xvel_new[lev-1]);
41  FillCoarsePatch(lev, time, yvel_new[lev], yvel_new[lev-1]);
42  FillCoarsePatch(lev, time, zvel_new[lev], zvel_new[lev-1]);
43 }
void init_stuff(int lev, const amrex::BoxArray &ba, const amrex::DistributionMapping &dm)
Definition: REMORA_make_new_level.cpp:191
void resize_stuff(int lev)
Definition: REMORA_make_new_level.cpp:137

◆ MakeNewLevelFromScratch()

void REMORA::MakeNewLevelFromScratch ( int  lev,
amrex::Real  time,
const amrex::BoxArray &  ba,
const amrex::DistributionMapping &  dm 
)
overridevirtual

Make a new level from scratch using provided BoxArray and DistributionMapping. Only used during initialization. Overrides the pure virtual function in AmrCore

104 {
105  // Set BoxArray grids and DistributionMapping dmap in AMReX_AmrMesh.H class
106  SetBoxArray(lev, ba);
107  SetDistributionMap(lev, dm);
108 
109  amrex::Print() << "GRIDS AT LEVEL " << lev << " ARE " << ba << std::endl;
110 
111  // The number of ghost cells for density must be 1 greater than that for velocity
112  // so that we can go back in forth between velocity and momentum on all faces
113 #if NGROW==2
114  int ngrow_state = ComputeGhostCells(solverChoice.spatial_order)+1;
115  int ngrow_vels = ComputeGhostCells(solverChoice.spatial_order)+1;
116 #else
117  int ngrow_state = ComputeGhostCells(solverChoice.spatial_order)+2;
118  int ngrow_vels = ComputeGhostCells(solverChoice.spatial_order)+2;
119 #endif
120 
121  cons_old[lev] = new MultiFab(ba, dm, NCONS, ngrow_state);
122  cons_new[lev] = new MultiFab(ba, dm, NCONS, ngrow_state);
123 
124  xvel_new[lev] = new MultiFab(convert(ba, IntVect(1,0,0)), dm, 1, ngrow_vels);
125  xvel_old[lev] = new MultiFab(convert(ba, IntVect(1,0,0)), dm, 1, ngrow_vels);
126 
127  yvel_new[lev] = new MultiFab(convert(ba, IntVect(0,1,0)), dm, 1, ngrow_vels);
128  yvel_old[lev] = new MultiFab(convert(ba, IntVect(0,1,0)), dm, 1, ngrow_vels);
129 
130  zvel_new[lev] = new MultiFab(convert(ba, IntVect(0,0,1)), dm, 1, IntVect(ngrow_vels,ngrow_vels,0));
131  zvel_old[lev] = new MultiFab(convert(ba, IntVect(0,0,1)), dm, 1, IntVect(ngrow_vels,ngrow_vels,0));
132 
133  resize_stuff(lev);
134  init_stuff(lev, ba, dm);
135 }
AMREX_FORCE_INLINE int ComputeGhostCells(const int &spatial_order)
Definition: REMORA.H:890
int spatial_order
Definition: DataStruct.H:237

◆ NumDataLogs()

AMREX_FORCE_INLINE int REMORA::NumDataLogs ( )
inlineprivatenoexcept
932  {
933  return datalog.size();
934  }

◆ PlotFileName()

std::string REMORA::PlotFileName ( int  lev) const
private

get plotfile name

◆ PlotFileVarNames()

Vector< std::string > REMORA::PlotFileVarNames ( amrex::Vector< std::string >  plot_var_names) const
private

set plotfile variables names

88 {
89  Vector<std::string> names;
90 
91  names.insert(names.end(), plot_var_names.begin(), plot_var_names.end());
92 
93  return names;
94 
95 }

◆ post_timestep()

void REMORA::post_timestep ( int  nstep,
amrex::Real  time,
amrex::Real  dt_lev 
)

Called after every level 0 timestep

232 {
233  BL_PROFILE("REMORA::post_timestep()");
234 
235 #ifdef REMORA_USE_PARTICLES
236  particleData.Redistribute();
237 #endif
238 
240  {
241  for (int lev = finest_level-1; lev >= 0; lev--)
242  {
243  // This call refluxes from the lev/lev+1 interface onto lev
244  getAdvFluxReg(lev+1)->Reflux(*cons_new[lev], 0, 0, NCONS);
245 
246  // We need to do this before anything else because refluxing changes the
247  // values of coarse cells underneath fine grids with the assumption they'll
248  // be over-written by averaging down
249  AverageDownTo(lev);
250  }
251  }
252 
253  if (is_it_time_for_action(nstep, time, dt_lev0, sum_interval, sum_per)) {
255  }
256 }
AMREX_FORCE_INLINE amrex::YAFluxRegister * getAdvFluxReg(int lev)
Definition: REMORA.H:917

◆ post_update()

void REMORA::post_update ( amrex::MultiFab &  state_mf,
const amrex::Real  time,
const amrex::Geometry &  geom 
)
private

◆ prestep()

void REMORA::prestep ( int  lev,
amrex::MultiFab &  mf_uold,
amrex::MultiFab &  mf_vold,
amrex::MultiFab &  mf_u,
amrex::MultiFab &  mf_v,
amrex::MultiFab *  mf_ru,
amrex::MultiFab *  mf_rv,
amrex::MultiFab &  S_old,
amrex::MultiFab &  S_new,
amrex::MultiFab &  mf_W,
amrex::MultiFab &  mf_DC,
const amrex::MultiFab *  mf_z_r,
const amrex::MultiFab *  mf_z_w,
const amrex::MultiFab *  mf_h,
const amrex::MultiFab *  mf_pm,
const amrex::MultiFab *  mf_pn,
const amrex::MultiFab *  mf_sustr,
const amrex::MultiFab *  mf_svstr,
const amrex::MultiFab *  mf_bustr,
const amrex::MultiFab *  mf_bvstr,
const int  iic,
const int  nfirst,
const int  nnew,
int  nstp,
int  nrhs,
int  N,
const amrex::Real  dt_lev 
)

Wrapper function for prestep

prestep

Parameters
[in]mf_vold
[in,out]mf_u(looks like reset in update_vel <- prestep_uv_3d, so maybe just out
[in,out]mf_vmaybe just out
[in,out]mf_ru
[in,out]mf_rv
[in]S_old
[in,out]S_new
[out]mf_W
[none] mf_DC (temp)
[in]mf_z_r
[in]mf_z_w
[in]mf_h
[in]mf_sustr
[in]mf_svstr
[in]mf_bustr
[in]mf_bvstr
[in]iic
[in]ntfirst
[in]nnew
[in]nstp
[in]nrhs
[in]N
[in]dt_lev
53 {
54  const BoxArray& ba = S_old.boxArray();
55  const DistributionMapping& dm = S_old.DistributionMap();
56 
57  // Maybe not the best way to do this, but need to cache salt and temp since
58  // they get rewritten by prestep_t
59  MultiFab mf_saltcache(ba,dm,1,IntVect(NGROW,NGROW,0));
60  MultiFab mf_tempcache(ba,dm,1,IntVect(NGROW,NGROW,0));
61 
62  MultiFab mf_scalarcache(ba,dm,NCONS,IntVect(NGROW,NGROW,0));
63  MultiFab::Copy(mf_scalarcache,S_new,0,0,NCONS,IntVect(NGROW,NGROW,0));
64 
65  MultiFab::Copy(mf_saltcache,S_new,Salt_comp,0,1,IntVect(NGROW,NGROW,0));
66  MultiFab::Copy(mf_tempcache,S_new,Temp_comp,0,1,IntVect(NGROW,NGROW,0));
67 
68  for ( MFIter mfi(S_new, TilingIfNotGPU()); mfi.isValid(); ++mfi )
69  {
70  Array4<Real> const& DC = mf_DC.array(mfi);
71  Array4<Real> const& Akv = vec_Akv[lev]->array(mfi);
72  Array4<Real> const& Akt = vec_Akt[lev]->array(mfi);
73  Array4<Real> const& Hz = vec_Hz[lev]->array(mfi);
74  Array4<Real> const& Huon = vec_Huon[lev]->array(mfi);
75  Array4<Real> const& Hvom = vec_Hvom[lev]->array(mfi);
76  Array4<Real const> const& uold = mf_uold.const_array(mfi);
77  Array4<Real const> const& vold = mf_vold.const_array(mfi);
78  Array4<Real> const& u = (mf_u).array(mfi);
79  Array4<Real> const& v = (mf_v).array(mfi);
80 
81  Array4<Real const> const& z_r = mf_z_r->const_array(mfi);
82  Array4<Real const> const& z_w = mf_z_w->const_array(mfi);
83  Array4<Real const> const& h = mf_h->const_array(mfi);
84  Array4<Real const> const& pm = mf_pm->const_array(mfi);
85  Array4<Real const> const& pn = mf_pn->const_array(mfi);
86 
87  Array4<Real > const& ru = mf_ru->array(mfi);
88  Array4<Real > const& rv = mf_rv->array(mfi);
89  Array4<Real > const& W = (mf_W).array(mfi);
90  Array4<Real const> const& sustr = mf_sustr->const_array(mfi);
91  Array4<Real const> const& svstr = mf_svstr->const_array(mfi);
92  Array4<Real const> const& bustr = mf_bustr->const_array(mfi);
93  Array4<Real const> const& bvstr = mf_bvstr->const_array(mfi);
94 
95  Real lambda = 1.0_rt;
96 
97  Box bx = mfi.tilebox();
98  Box gbx = mfi.growntilebox();
99  Box gbx1 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
100  Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
101  //Box gbx11 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,NGROW-1));
102 
103  //copy the tilebox
104  Box tbxp1 = bx;
105  Box tbxp11 = bx;
106  Box tbxp2 = bx;
107 
108  //TODO: adjust for tiling
109  //Box gbx3uneven(IntVect(AMREX_D_DECL(bx.smallEnd(0)-3,bx.smallEnd(1)-3,bx.smallEnd(2))),
110  // IntVect(AMREX_D_DECL(bx.bigEnd(0)+2,bx.bigEnd(1)+2,bx.bigEnd(2))));
111  //Box gbx2uneven(IntVect(AMREX_D_DECL(bx.smallEnd(0)-2,bx.smallEnd(1)-2,bx.smallEnd(2))),
112  // IntVect(AMREX_D_DECL(bx.bigEnd(0)+1,bx.bigEnd(1)+1,bx.bigEnd(2))));
113  //make only gbx be grown to match multifabs
114  tbxp2.grow(IntVect(NGROW,NGROW,0));
115  tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
116  tbxp11.grow(IntVect(NGROW-1,NGROW-1,NGROW-1));
117 
118  Box bxD = bx;
119  bxD.makeSlab(2,0);
120  Box gbx1D = gbx1;
121  gbx1D.makeSlab(2,0);
122  Box gbx2D = gbx2;
123  gbx2D.makeSlab(2,0);
124 
125  Box tbxp1D = tbxp1;
126  tbxp1D.makeSlab(2,0);
127  Box tbxp2D = tbxp2;
128  tbxp2D.makeSlab(2,0);
129 
130  FArrayBox fab_FC(tbxp2,1,amrex::The_Async_Arena()); //3D
131 
132  auto FC=fab_FC.array();
133 
134  //From ini_fields and .in file
135  //fab_Akt.setVal(1e-6);
136  FArrayBox fab_stflux(tbxp2,1,amrex::The_Async_Arena());
137  auto stflux= fab_stflux.array();
138  FArrayBox fab_btflux(tbxp2,1,amrex::The_Async_Arena());
139  auto btflux= fab_btflux.array();
140 
141  //From ini_fields and .in file
142  //fab_stflux.setVal(0.0_rt);
143  //also set btflux=0 (as in ana_btflux.H)
144  ParallelFor(tbxp2,
145  [=] AMREX_GPU_DEVICE (int i, int j, int k)
146  {
147  stflux(i,j,k)=0.0_rt;
148  btflux(i,j,k)=0.0_rt;
149  });
150 
151  for (int i_comp=0; i_comp < NCONS; i_comp++) {
152  Array4<Real> const& sstore = (vec_sstore[lev])->array(mfi,i_comp);
153  prestep_t_advection(bx, gbx, S_old.array(mfi,i_comp),
154  mf_scalarcache.array(mfi,i_comp), Hz, Huon, Hvom,
155  W, DC, FC, sstore, z_w, h, pm, pn, iic, ntfirst,
156  nrhs, N, dt_lev);
157  }
158 
159  // Only do diffusion for salt and temperature, not other tracer(s)
160  for (int i_comp=0; i_comp < NCONS; i_comp++) {
161  prestep_diffusion(bx,gbx,0,0,S_new.array(mfi,i_comp), S_old.array(mfi,i_comp), ru,
162  Hz, Akt, DC, FC, stflux, btflux, z_r, pm, pn, iic, iic, nnew, nstp,
163  nrhs, N, lambda, dt_lev);
164  }
165 
166  //
167  //-----------------------------------------------------------------------
168  // prestep_uv_3d
169  //-----------------------------------------------------------------------
170  //
171  //updates u,v,ru,rv (ru and rv have multiple components)
172 
173  prestep_diffusion(tbxp1, gbx, 1, 0, u, uold, ru, Hz, Akv, DC, FC,
174  sustr, bustr, z_r, pm, pn, iic, ntfirst, nnew, nstp, nrhs, N, lambda, dt_lev);
175 
176  prestep_diffusion(tbxp1, gbx, 0, 1, v, vold, rv, Hz, Akv, DC, FC,
177  svstr, bvstr, z_r, pm, pn, iic, ntfirst, nnew, nstp, nrhs, N, lambda, dt_lev);
178  }
179 }
#define Temp_comp
Definition: IndexDefines.H:8
#define Salt_comp
Definition: IndexDefines.H:9
void prestep_diffusion(const amrex::Box &bx, const amrex::Box &gbx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &vel, const amrex::Array4< amrex::Real const > &vel_old, const amrex::Array4< amrex::Real > &rvel, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &Akv, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real const > &sstr, const amrex::Array4< amrex::Real const > &bstr, const amrex::Array4< amrex::Real const > &z_r, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, const int iic, const int ntfirst, const int nnew, int nstp, int nrhs, int N, const amrex::Real lambda, const amrex::Real dt_lev)
Definition: REMORA_prestep_diffusion.cpp:19
void prestep_t_advection(const amrex::Box &tbx, const amrex::Box &gbx, const amrex::Array4< amrex::Real > &tempold, const amrex::Array4< amrex::Real > &tempcache, const amrex::Array4< amrex::Real > &Hz, const amrex::Array4< amrex::Real > &Huon, const amrex::Array4< amrex::Real > &Hvom, const amrex::Array4< amrex::Real > &W, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real > &sstore, const amrex::Array4< amrex::Real const > &z_w, const amrex::Array4< amrex::Real const > &h, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, int iic, int ntfirst, int nrhs, int N, const amrex::Real dt_lev)
Definition: REMORA_prestep_t_advection.cpp:10

◆ prestep_diffusion()

void REMORA::prestep_diffusion ( const amrex::Box &  bx,
const amrex::Box &  gbx,
const int  ioff,
const int  joff,
const amrex::Array4< amrex::Real > &  vel,
const amrex::Array4< amrex::Real const > &  vel_old,
const amrex::Array4< amrex::Real > &  rvel,
const amrex::Array4< amrex::Real const > &  Hz,
const amrex::Array4< amrex::Real const > &  Akv,
const amrex::Array4< amrex::Real > &  DC,
const amrex::Array4< amrex::Real > &  FC,
const amrex::Array4< amrex::Real const > &  sstr,
const amrex::Array4< amrex::Real const > &  bstr,
const amrex::Array4< amrex::Real const > &  z_r,
const amrex::Array4< amrex::Real const > &  pm,
const amrex::Array4< amrex::Real const > &  pn,
const int  iic,
const int  ntfirst,
const int  nnew,
int  nstp,
int  nrhs,
int  N,
const amrex::Real  lambda,
const amrex::Real  dt_lev 
)

Update velocities or tracers with diffusion/viscosity as the last part of the prestep

35 {
36 
37  BoxArray ba_gbxvel = intersect(BoxArray(vel_bx), gbx);
38  AMREX_ASSERT((ba_gbxvel.size() == 1));
39  Box gbxvel = ba_gbxvel[0];
40 
41  //
42  // Weighting coefficient for the newest (implicit) time step derivatives
43  // using either a Crank-Nicolson implicit scheme (lambda=0.5) or a
44  // backward implicit scheme (lambda=1.0).
45  //
46 
47  Real oml_dt = dt_lev*(1.0-lambda);
48  //N is one less than ROMS
49 
50  // Except the commented out part means lambda is always 1.0
51  if (verbose > 1) {
52  amrex::Print() << "in update_vel_3d with box " << vel_bx << std::endl;
53  Print() << "vel old " << Box(vel_old) << std::endl;
54  Print() << "Akv " << Box(Akv) << std::endl;
55  }
56  ParallelFor(vel_bx,
57  [=] AMREX_GPU_DEVICE (int i, int j, int k)
58  {
59  if(k+1<=N&&k>=0)
60  {
61  Real cff = 1.0 / ( z_r(i,j,k+1)+z_r(i-ioff,j-joff,k+1)
62  -z_r(i,j,k )-z_r(i-ioff,j-joff,k ));
63  FC(i,j,k) = oml_dt * cff * (vel_old(i,j,k+1,nstp)-vel_old(i,j,k,nstp)) *
64  (Akv(i,j,k) +Akv(i-ioff,j-joff,k));
65  }
66  else if (k==-1)
67  {
68  FC(i,j,-1) = dt_lev*bstr(i,j,0);
69  }
70  else if (k==N)
71  {
72  FC(i,j, N) = dt_lev*sstr(i,j,0);
73  }
74 
75  DC(i,j,k) = 0.25 * dt_lev * (pm(i,j,0)+pm(i-ioff,j-joff,0))
76  * (pn(i,j,0)+pn(i-ioff,j-joff,0));
77  });
78 
79  ParallelFor(gbxvel,
80  [=] AMREX_GPU_DEVICE (int i, int j, int k)
81  {
82  Real cff3=dt_lev*(1.0-lambda);
83  Real cff1 = 0.0, cff2 = 0.0, cff4;
84 
85  int indx=0; //nrhs-3
86 
87  if (iic==ntfirst)
88  {
89  if (k+1<=N && k>=1)
90  {
91  cff1=vel_old(i,j,k,nstp)*0.5*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
92  cff2=FC(i,j,k)-FC(i,j,k-1);
93  vel(i,j,k,nnew)=cff1+cff2;
94  }
95  else if(k==0)
96  {
97  cff1=vel_old(i,j,k,nstp)*0.5*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
98  cff2=FC(i,j,k)-dt_lev*bstr(i,j,0);
99  vel(i,j,k,nnew)=cff1+cff2;
100  }
101  else if(k==N)
102  {
103  cff1=vel_old(i,j,k,nstp)*0.5*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
104  cff2=dt_lev*sstr(i,j,0)-FC(i,j,k-1); //or: -FC(i,j,k-1)+dt_lev*sstr(i,j,0);
105  vel(i,j,k,nnew)=cff1+cff2;
106  }
107 
108  } else if(iic==ntfirst+1) {
109 
110  if (k<N && k>0) {
111  cff1=vel_old(i,j,k,nstp)*0.5*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
112  cff2=FC(i,j,k)-FC(i,j,k-1);
113  }
114  else if(k==0) {
115  cff1=vel_old(i,j,k,nstp)*0.5*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
116  cff2=FC(i,j,k)-dt_lev*bstr(i,j,0);
117  }
118  else if(k==N) {
119  cff1=vel_old(i,j,k,nstp)*0.5*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
120  cff2=dt_lev*sstr(i,j,0)-FC(i,j,k-1); //or: -FC(i,j,k-1)+dt_lev*sstr(i,j,0);
121  }
122 
123  cff3=0.5*DC(i,j,k);
124 
125  if (ioff==0&&joff==0) {
126  vel(i,j,k,nnew)=cff1 + cff2;
127  } else {
128  indx=nrhs ? 0 : 1;
129  Real r_swap= rvel(i,j,k,indx);
130  rvel(i,j,k,indx) = rvel(i,j,k,nrhs);
131  rvel(i,j,k,nrhs) = r_swap;
132  vel(i,j,k,nnew)=cff1- cff3*rvel(i,j,k,indx)+ cff2;
133  }
134  } else {
135  cff1 = 5.0/12.0;
136  cff2 = 16.0/12.0;
137  if (k==0) {
138  cff3=vel_old(i,j,k,nstp)*0.5*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
139  cff4=FC(i,j,k)-dt_lev*bstr(i,j,0);
140  //cff4=FC(i,j,k)-FC(i,j,k-1);//-bustr(i,j,0);
141 
142  } else if (k == N) {
143  cff3=vel_old(i,j,k,nstp)*0.5*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
144  cff4=dt_lev*sstr(i,j,0)-FC(i,j,k-1);
145 
146  } else {
147  cff3=vel_old(i,j,k,nstp)*0.5*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
148  cff4=FC(i,j,k)-FC(i,j,k-1);
149  }
150 
151  if (ioff==0 && joff==0) {
152  vel(i,j,k,nnew) = cff3 + cff4;
153  } else {
154  indx=nrhs ? 0 : 1;
155  Real r_swap= rvel(i,j,k,indx);
156  rvel(i,j,k,indx) = rvel(i,j,k,nrhs);
157  rvel(i,j,k,nrhs) = r_swap;
158 
159  vel(i,j,k,nnew) = cff3 + DC(i,j,k)*(cff1*rvel(i,j,k,nrhs)-
160  cff2*rvel(i,j,k,indx))+
161  cff4;
162  rvel(i,j,k,nrhs) = 0.0;
163  }
164  }
165  });
166 }

◆ prestep_t_advection()

void REMORA::prestep_t_advection ( const amrex::Box &  tbx,
const amrex::Box &  gbx,
const amrex::Array4< amrex::Real > &  tempold,
const amrex::Array4< amrex::Real > &  tempcache,
const amrex::Array4< amrex::Real > &  Hz,
const amrex::Array4< amrex::Real > &  Huon,
const amrex::Array4< amrex::Real > &  Hvom,
const amrex::Array4< amrex::Real > &  W,
const amrex::Array4< amrex::Real > &  DC,
const amrex::Array4< amrex::Real > &  FC,
const amrex::Array4< amrex::Real > &  sstore,
const amrex::Array4< amrex::Real const > &  z_w,
const amrex::Array4< amrex::Real const > &  h,
const amrex::Array4< amrex::Real const > &  pm,
const amrex::Array4< amrex::Real const > &  pn,
int  iic,
int  ntfirst,
int  nrhs,
int  N,
const amrex::Real  dt_lev 
)

Prestep calculations for the tracers

26 {
27  //copy the tilebox
28  Box gbx1 = tbx;
29  Box gbx2 = tbx;
30  Box tbxp1 = tbx;
31  Box tbxp2 = tbx;
32 
33  tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
34  tbxp2.grow(IntVect(NGROW,NGROW,0));
35  FArrayBox fab_FX(tbxp2,1,amrex::The_Async_Arena()); //3D
36  FArrayBox fab_FE(tbxp2,1,amrex::The_Async_Arena()); //3D
37  FArrayBox fab_curv(tbxp2,1,amrex::The_Async_Arena()); //fab_curv.setVal(0.0_rt);
38  FArrayBox fab_grad(tbxp2,1,amrex::The_Async_Arena()); //fab_curv.setVal(0.0_rt);
39 
40  auto FX=fab_FX.array();
41  auto FE=fab_FE.array();
42  auto curv=fab_curv.array();
43  auto grad=fab_grad.array();
44  ParallelFor(tbxp2,
45  [=] AMREX_GPU_DEVICE (int i, int j, int k)
46  {
47  grad(i,j,k)=0.0_rt;
48 
49  curv(i,j,k)=0.0_rt;
50 
51  FX(i,j,k)=0.0_rt;
52  FE(i,j,k)=0.0_rt;
53  });
54 
55 
56  Box ubx = surroundingNodes(tbx,0);
57  Box vbx = surroundingNodes(tbx,1);
58 
59  Box utbxp1 = surroundingNodes(tbxp1,0);
60  Box vtbxp1 = surroundingNodes(tbxp1,1);
61 
62  Box gbx3uneven_init(IntVect(AMREX_D_DECL(tbx.smallEnd(0)-3,tbx.smallEnd(1)-3,tbx.smallEnd(2))),
63  IntVect(AMREX_D_DECL(tbx.bigEnd(0)+2,tbx.bigEnd(1)+2,tbx.bigEnd(2))));
64  BoxArray ba_gbx3uneven = intersect(BoxArray(gbx3uneven_init), gbx);
65  AMREX_ASSERT((ba_gbx3uneven.size() == 1));
66  Box gbx3uneven = ba_gbx3uneven[0];
67 
68  gbx2.grow(IntVect(NGROW,NGROW,0));
69  BoxArray ba_gbx2 = intersect(BoxArray(gbx2), gbx);
70  AMREX_ASSERT((ba_gbx2.size() == 1));
71  gbx2 = ba_gbx2[0];
72 
73  gbx1.grow(IntVect(NGROW-1,NGROW-1,0));
74  BoxArray ba_gbx1 = intersect(BoxArray(gbx1), gbx);
75  AMREX_ASSERT((ba_gbx1.size() == 1));
76  gbx1 = ba_gbx1[0];
77 
78  //------------------------------------------------------------------------
79  // Vertically integrate horizontal mass flux divergence.
80  //------------------------------------------------------------------------
81  //
82  //Should really use gbx3uneven
83  Box gbx3unevenD = gbx3uneven;
84  gbx3unevenD.makeSlab(2,0);
85  Box gbx1D = gbx1;
86  gbx1D.makeSlab(2,0);
87 
88  ParallelFor(gbx1D,
89  [=] AMREX_GPU_DEVICE (int i, int j, int )
90  {
91  // Starting with zero vertical velocity at the bottom, integrate
92  // from the bottom (k=0) to the free-surface (k=N). The w(:,:,N(ng))
93  // contains the vertical velocity at the free-surface, d(zeta)/d(t).
94  // Notice that barotropic mass flux divergence is not used directly.
95  //
96  //W(i,j,-1)=0.0_rt;
97  int k=0;
98  W(i,j,k) = -(Huon(i+1,j,k)-Huon(i,j,k)) - (Hvom(i,j+1,k)-Hvom(i,j,k));
99  for(k=1;k<=N;k++) {
100  W(i,j,k) = W(i,j,k-1) - (Huon(i+1,j,k)-Huon(i,j,k)) - (Hvom(i,j+1,k)-Hvom(i,j,k));
101  }
102  });
103  ParallelFor(gbx1,
104  [=] AMREX_GPU_DEVICE (int i, int j, int k)
105  {
106  // Starting with zero vertical velocity at the bottom, integrate
107  // from the bottom (k=0) to the free-surface (k=N). The w(:,:,N(ng))
108  // contains the vertical velocity at the free-surface, d(zeta)/d(t).
109  // Notice that barotropic mass flux divergence is not used directly.
110  //
111  Real wrk_i=W(i,j,N)/(z_w(i,j,N)+h(i,j,0,0));
112 
113  if(k!=N) {
114  W(i,j,k) = W(i,j,k)- wrk_i*(z_w(i,j,k)+h(i,j,0,0));
115  }
116  });
117 
118  ParallelFor(gbx1,
119  [=] AMREX_GPU_DEVICE (int i, int j, int k)
120  {
121  if (k == N) {
122  W(i,j,N) = 0.0_rt;
123  }
124  });
125 
126  //From ini_fields and .in file
127  //fab_Akt.setVal(1e-6);
128  FArrayBox fab_stflux(tbxp2,1,amrex::The_Async_Arena());
129  auto stflux= fab_stflux.array();
130  FArrayBox fab_btflux(tbxp2,1,amrex::The_Async_Arena());
131  auto btflux= fab_btflux.array();
132 
133  //From ini_fields and .in file
134  //fab_stflux.setVal(0.0_rt);
135  //also set btflux=0 (as in ana_btflux.H)
136 
137  ParallelFor(tbxp2, [=] AMREX_GPU_DEVICE (int i, int j, int k)
138  {
139  stflux(i,j,k)=0.0_rt;
140  btflux(i,j,k)=0.0_rt;
141  });
142 
143  //Use FC and DC as intermediate arrays for FX and FE
144  //First pass do centered 2d terms
145 
147  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
148  {
149  FX(i,j,k)=Box(tempold).contains(i-1,j,k) ? Huon(i,j,k)*
150  0.5_rt*(tempold(i-1,j,k)+tempold(i ,j,k)) : 1e34;
151  });
152  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
153  {
154  FE(i,j,k)=Box(tempold).contains(i,j-1,k) ? Hvom(i,j,k)*
155  0.5_rt*(tempold(i,j-1,k)+tempold(i,j,k)) : 1e34;
156  });
157 
158  } else {
159 
160  ParallelFor(utbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
161  {
162  //should be t index 3
163  FX(i,j,k)=tempold(i,j,k,nrhs)-tempold(i-1,j,k,nrhs);
164  });
165 
166  ParallelFor(vtbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
167  {
168  //should be t index 3
169  FE(i,j,k)=tempold(i,j,k,nrhs)-tempold(i,j-1,k,nrhs);
170  });
171 
172  Real cffa=1.0_rt/6.0_rt;
173  Real cffb=1.0_rt/3.0_rt;
175  {
176  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
177  {
178  //Upstream3
179  curv(i,j,k)=-FX(i,j,k)+FX(i+1,j,k);
180  });
181 
182  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
183  {
184  Real max_Huon = std::max(Huon(i,j,k),0.0_rt);
185  Real min_Huon = std::min(Huon(i,j,k),0.0_rt);
186 
187  FX(i,j,k)=Huon(i,j,k)*0.5_rt*(tempold(i,j,k)+tempold(i-1,j,k))-
188  cffa*(curv(i,j,k)*min_Huon+ curv(i-1,j,k)*max_Huon);
189  });
190 
192 
193  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
194  {
195  //Centered4
196  grad(i,j,k)=0.5_rt*(FX(i,j,k)+FX(i+1,j,k));
197  });
198 
199  ParallelFor(ubx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
200  {
201  FX(i,j,k)=Huon(i,j,k)*0.5_rt*(tempold(i,j,k)+tempold(i-1,j,k)-
202  cffb*(grad(i,j,k)-grad(i-1,j,k)));
203  });
204  } else {
205  Error("Not a valid horizontal advection scheme");
206  }
207 
209  {
210  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
211  {
212  curv(i,j,k)=-FE(i,j,k)+FE(i,j+1,k);
213  });
214 
215  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
216  {
217  Real max_Hvom = std::max(Hvom(i,j,k),0.0_rt);
218  Real min_Hvom = std::min(Hvom(i,j,k),0.0_rt);
219 
220  FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(tempold(i,j,k)+tempold(i,j-1,k))-
221  cffa*(curv(i,j,k)*min_Hvom+ curv(i,j-1,k)*max_Hvom);
222  });
223 
225 
226  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
227  {
228  grad(i,j,k)=0.5_rt*(FE(i,j,k)+FE(i,j+1,k));
229  });
230 
231  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
232  {
233  FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(tempold(i,j,k)+tempold(i,j-1,k)-
234  cffb*(grad(i,j,k)- grad(i,j-1,k)));
235  });
236  } else {
237  Error("Not a valid horizontal advection scheme");
238  }
239  } // not flat
240 
241  //Intermediate tracer at 3
242  //
243  // Time-step horizontal advection (m Tunits).
244  //
245 
246  Real cff1 = 0.0_rt, cff2 = 0.0_rt, cff;
247 
248  Real GammaT = 1.0_rt/6.0_rt;
249 
250  if (iic==ntfirst)
251  {
252  cff=0.5_rt*dt_lev;
253  cff1=1.0_rt;
254  cff2=0.0_rt;
255  } else {
256  cff=(1.0_rt-GammaT)*dt_lev;
257  cff1=0.5_rt+GammaT;
258  cff2=0.5_rt-GammaT;
259  }
260 
261  ParallelFor(tbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
262  {
263  tempstore(i,j,k)=Hz(i,j,k)*( cff1 * tempold(i,j,k)+
264  cff2 * tempcache(i,j,k) )-
265  cff * pm(i,j,0)*pn(i,j,0) * (FX(i+1,j,k)-FX(i,j,k)+
266  FE(i,j+1,k)-FE(i,j,k));
267  });
268 
269  //
270  // Time-step vertical advection of tracers (Tunits). Impose artificial
271  // continuity equation.
272  //
273  ParallelFor(tbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
274  {
275  //-----------------------------------------------------------------------
276  // Add in vertical advection.
277  //-----------------------------------------------------------------------
278 
279  Real c1=0.5_rt;
280  Real c2=7.0_rt/12.0_rt;
281  Real c3=1.0_rt/12.0_rt;
282 
283  if (k>=1 && k<=N-2)
284  {
285  FC(i,j,k)=( c2*(tempold(i ,j,k ,nrhs)+ tempold(i,j,k+1,nrhs))
286  -c3*(tempold(i ,j,k-1,nrhs)+ tempold(i,j,k+2,nrhs)) )*
287  ( W(i,j,k));
288  }
289  else // this needs to be split up so that the following can be concurrent
290  {
291  FC(i,j,N)=0.0_rt;
292 
293  FC(i,j,N-1) = ( c2*tempold(i,j,N-1,nrhs)+ c1*tempold(i,j,N,nrhs)-c3*tempold(i,j,N-2,nrhs) )
294  * W(i,j,N-1);
295 
296  FC(i,j, 0) = ( c2*tempold(i,j, 1,nrhs)+ c1*tempold(i,j,0,nrhs)-c3*tempold(i,j,2,nrhs) )
297  * W(i,j,0);
298  }
299  });
300 
301  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
302  {
303  if(k-1>=0) {
304  DC(i,j,k)=1.0_rt/(Hz(i,j,k)-
305  cff*pm(i,j,0)*pn(i,j,0)*
306  (Huon(i+1,j,k)-Huon(i,j,k)+
307  Hvom(i,j+1,k)-Hvom(i,j,k)+
308  (W(i,j,k)-W(i,j,k-1))));
309  } else {
310  DC(i,j,k)=1.0_rt/(Hz(i,j,k)-
311  cff*pm(i,j,0)*pn(i,j,0)*
312  (Huon(i+1,j,k)-Huon(i,j,k)+
313  Hvom(i,j+1,k)-Hvom(i,j,k)+
314  (W(i,j,k))));
315  }
316  });
317 
318  ParallelFor(tbx,
319  [=] AMREX_GPU_DEVICE (int i, int j, int k)
320  {
321  Real c1 = cff*pm(i,j,0)*pn(i,j,0);
322 
323  Real c4 = (k>0) ? FC(i,j,k)-FC(i,j,k-1) : FC(i,j,k);
324 
325  tempstore(i,j,k) = DC(i,j,k)*(tempstore(i,j,k)-c1*c4);
326  });
327 
328 }
AdvectionScheme Hadv_scheme
Definition: DataStruct.H:202
bool flat_bathymetry
Definition: DataStruct.H:189

◆ prsgrd()

void REMORA::prsgrd ( const amrex::Box &  bx,
const amrex::Box &  gbx,
const amrex::Box &  utbx,
const amrex::Box &  vtbx,
const amrex::Array4< amrex::Real > &  ru,
const amrex::Array4< amrex::Real > &  rv,
const amrex::Array4< amrex::Real const > &  pn,
const amrex::Array4< amrex::Real const > &  pm,
const amrex::Array4< amrex::Real const > &  rho,
const amrex::Array4< amrex::Real > &  FC,
const amrex::Array4< amrex::Real const > &  Hz,
const amrex::Array4< amrex::Real const > &  z_r,
const amrex::Array4< amrex::Real const > &  z_w,
const int  nrhs,
const int  N 
)
18 {
19  auto phi_bxD=phi_bx;
20  phi_bxD.makeSlab(2,0);
21  auto phi_gbxD=phi_gbx & phi_bx;
22  phi_gbxD.makeSlab(2,0);
23  Box phi_ubx = surroundingNodes(phi_bx,0);
24  Box phi_vbx = surroundingNodes(phi_bx,1);
25  auto utbxD = utbx;
26  auto vtbxD = vtbx;
27  utbxD.makeSlab(2,0);
28  vtbxD.makeSlab(2,0);
29 
30  const Real OneFifth = 0.2_rt;
31  const Real OneTwelfth = 1.0_rt/12.0_rt;
32  const Real eps = 1.0E-10_rt;
34  Real GRho0 = 1000.0_rt * GRho;
35  Real HalfGRho = 0.5_rt * GRho;
36 
37  FArrayBox fab_P(phi_bx,1,The_Async_Arena());
38  FArrayBox fab_aux(Box(z_r),1,The_Async_Arena());
39  FArrayBox fab_dR(phi_bx,1,The_Async_Arena());
40  FArrayBox fab_dZ(phi_bx,1,The_Async_Arena());
41  FArrayBox fab_dRx(phi_bx,1,The_Async_Arena());
42  FArrayBox fab_dZx(phi_bx,1,The_Async_Arena());
43 
44  auto P=fab_P.array();
45  auto aux=fab_aux.array();
46  auto dR=fab_dR.array();
47  auto dZ=fab_dZ.array();
48  auto dRx=fab_dRx.array();
49  auto dZx=fab_dZx.array();
50 
51  // Derivatives in the z direction
52  ParallelFor(phi_bx,
53  [=] AMREX_GPU_DEVICE (int i, int j, int k)
54  {
55  if(k>=0&&k<N) {
56  dR(i,j,k)=rho(i,j,k+1)-rho(i,j,k);
57  dZ(i,j,k)=z_r(i,j,k+1)-z_r(i,j,k);
58  } else {
59  dR(i,j,N)=rho(i,j,N)-rho(i,j,N-1);
60  dZ(i,j,N)=z_r(i,j,N)-z_r(i,j,N-1);
61  }
62  });
63 
64  ParallelFor(phi_bxD,
65  [=] AMREX_GPU_DEVICE (int i, int j, int )
66  {
67  for(int k=N;k>=0;k--) {
68  Real cff= k>0 ? 2.0*dR(i,j,k)*dR(i,j,k-1) : 2.0*dR(i,j,k)*dR(i,j,k);
69  if (cff>eps) {
70  dR(i,j,k)= k>0 ? cff/(dR(i,j,k)+dR(i,j,k-1)) : cff/(dR(i,j,k)+dR(i,j,k));
71  } else {
72  dR(i,j,k)=0.0;
73  }
74  dZ(i,j,k)= k>0 ? 2.0_rt*dZ(i,j,k)*dZ(i,j,k-1)/(dZ(i,j,k)+dZ(i,j,k-1)) :
75  2.0_rt*dZ(i,j,k)*dZ(i,j,k)/(dZ(i,j,k)+dZ(i,j,k));
76  }
77  });
78 
79  ParallelFor(phi_bxD,
80  [=] AMREX_GPU_DEVICE (int i, int j, int )
81  {
82  Real cff1=1.0_rt/(z_r(i,j,N)-z_r(i,j,N-1));
83  Real cff2=0.5_rt*(rho(i,j,N)-rho(i,j,N-1))*(z_w(i,j,N)-z_r(i,j,N))*cff1;
84 
85  P(i,j,N)=GRho0*z_w(i,j,N)+GRho*(rho(i,j,N)+cff2)*(z_w(i,j,N)-z_r(i,j,N));
86 
87  for (int k=N-1;k>=0;k--)
88  {
89  Real rho_diff = rho(i,j,k+1)-rho(i,j,k) - OneTwelfth* (dR(i,j,k+1)+dR(i,j,k));
90  Real z_diff = z_r(i,j,k+1)-z_r(i,j,k) - OneTwelfth* (dZ(i,j,k+1)+dZ(i,j,k));
91  Real rz_avg = (rho(i,j,k+1)+rho(i,j,k)) * (z_r(i,j,k+1)-z_r(i,j,k));
92 
93  P(i,j,k) = P(i,j,k+1) + HalfGRho * ( rz_avg -
94  OneFifth* ( (dR(i,j,k+1)-dR(i,j,k)) * z_diff -
95  (dZ(i,j,k+1)-dZ(i,j,k)) * rho_diff ) );
96  }
97  });
98 
99  //This should be nodal
100  // Derivatives in the x direction
101  ParallelFor(phi_ubx,
102  [=] AMREX_GPU_DEVICE (int i, int j, int k)
103  {
104  FC(i,j,k)=rho(i,j,k)-rho(i-1,j,k);
105  aux(i,j,k)=z_r(i,j,k)-z_r(i-1,j,k);
106  });
107 
108  //This should be nodal aux and FC need wider boxes above
109  //dZx and dRx may have index mismatch issues at k=2 and k=N
110  ParallelFor(phi_bxD,
111  [=] AMREX_GPU_DEVICE (int i, int j, int )
112  {
113  for(int k=N;k>=0;k--) {
114  Real cff= 2.0*aux(i,j,k)*aux(i+1,j,k);
115  if (cff>eps) {
116  Real cff1= 1.0_rt/(aux(i+1,j,k)+aux(i,j,k));
117  dZx(i,j,k)=cff*cff1;
118  } else {
119  dZx(i,j,k)=0.0;
120  }
121  Real cff1= 2.0*FC(i,j,k)*FC(i+1,j,k);
122  if (cff1>eps) {
123  Real cff2= 1.0_rt/(FC(i,j,k)+FC(i+1,j,k));
124  dRx(i,j,k)=cff1*cff2;
125  } else {
126  dRx(i,j,k)=0.0;
127  }
128  }
129  });
130 
131  //This should be nodal aux and FC need wider boxes above
132  ParallelFor(utbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
133  {
134  for(int k=N;k>=0;k--)
135  {
136  Real rho_diff = rho(i,j,k)-rho(i-1,j,k)- OneTwelfth* (dRx(i,j,k)+dRx(i-1,j,k));
137  Real z_r_diff = z_r(i,j,k)-z_r(i-1,j,k)- OneTwelfth* (dZx(i,j,k)+dZx(i-1,j,k));
138  Real Hz_avg = 0.5_rt * (Hz(i,j,k)+Hz(i-1,j,k));
139 
140  Real on_u = 2.0_rt / (pn(i-1,j,0)+pn(i,j,0));
141  ru(i,j,k,nrhs) = on_u * Hz_avg * (
142  P(i-1,j,k) - P(i,j,k) - HalfGRho *
143  ( (rho(i,j,k)+rho(i-1,j,k))*(z_r(i,j,k)-z_r(i-1,j,k))-
144  OneFifth * ( (dRx(i,j,k)-dRx(i-1,j,k)) * z_r_diff -
145  (dZx(i,j,k)-dZx(i-1,j,k)) * rho_diff ) ) );
146  }
147  });
148 
149  //This should be nodal
150  ParallelFor(phi_vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
151  {
152  FC(i,j,k)= rho(i,j,k)-rho(i,j-1,k);
153  aux(i,j,k)= z_r(i,j,k)-z_r(i,j-1,k);
154  });
155 
156  //This should be nodal aux and FC need wider boxes above
157  //dZx and dRx may have index mismatch issues at k=2 and k=N
158  ParallelFor(phi_bxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
159  {
160  for(int k=N;k>=0;k--) {
161  Real cff= 2.0*aux(i,j,k)*aux(i,j+1,k);
162  if (cff>eps) {
163  Real cff1= 1.0_rt/(aux(i,j+1,k)+aux(i,j,k));
164  dZx(i,j,k)=cff*cff1;
165  } else {
166  dZx(i,j,k)=0.0;
167  }
168  Real cff1= 2.0*FC(i,j,k)*FC(i,j+1,k);
169  if (cff1>eps) {
170  Real cff2= 1.0_rt/(FC(i,j,k)+FC(i,j+1,k));
171  dRx(i,j,k)=cff1*cff2;
172  } else {
173  dRx(i,j,k)=0.0;
174  }
175  }
176  });
177 
178  //This should be nodal aux and FC need wider boxes above
179  ParallelFor(vtbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
180  {
181  for (int k=N;k>=0;k--)
182  {
183  Real rho_diff = rho(i,j,k)-rho(i,j-1,k)- OneTwelfth* (dRx(i,j,k)+dRx(i,j-1,k));
184  Real z_r_diff = z_r(i,j,k)-z_r(i,j-1,k)- OneTwelfth* (dZx(i,j,k)+dZx(i,j-1,k));
185  Real Hz_avg = 0.5_rt * (Hz(i,j,k)+Hz(i,j-1,k));
186 
187  Real om_v = 2.0_rt / (pm(i,j-1,0)+pm(i,j,0));
188  rv(i,j,k,nrhs) = om_v * Hz_avg * (
189  P(i,j-1,k) - P(i,j,k) - HalfGRho *
190  ( (rho(i,j,k)+rho(i,j-1,k))*(z_r(i,j,k)-z_r(i,j-1,k))-
191  OneFifth * ( (dRx(i,j,k)-dRx(i,j-1,k)) * z_r_diff -
192  (dZx(i,j,k)-dZx(i,j-1,k)) * rho_diff ) ) );
193  } // k
194  });
195 }
amrex::Real rho0
Definition: DataStruct.H:227

◆ ReadCheckpointFile()

void REMORA::ReadCheckpointFile ( )
private
215 {
216  amrex::Print() << "Restart from checkpoint " << restart_chkfile << "\n";
217 
218  // Header
219  std::string File(restart_chkfile + "/Header");
220 
221  VisMF::IO_Buffer io_buffer(VisMF::GetIOBufferSize());
222 
223  Vector<char> fileCharPtr;
224  ParallelDescriptor::ReadAndBcastFile(File, fileCharPtr);
225  std::string fileCharPtrString(fileCharPtr.dataPtr());
226  std::istringstream is(fileCharPtrString, std::istringstream::in);
227 
228  std::string line, word;
229 
230  int chk_ncomp;
231 
232  // read in title line
233  std::getline(is, line);
234 
235  // read in finest_level
236  is >> finest_level;
237  GotoNextLine(is);
238 
239  // read the number of components
240  // for each variable we store
241 
242  // conservative, cell-centered vars
243  is >> chk_ncomp;
244  GotoNextLine(is);
245  AMREX_ASSERT(chk_ncomp == NCONS);
246 
247  // x-velocity on faces
248  is >> chk_ncomp;
249  GotoNextLine(is);
250  AMREX_ASSERT(chk_ncomp == 1);
251 
252  // y-velocity on faces
253  is >> chk_ncomp;
254  GotoNextLine(is);
255  AMREX_ASSERT(chk_ncomp == 1);
256 
257  // z-velocity on faces
258  is >> chk_ncomp;
259  GotoNextLine(is);
260  AMREX_ASSERT(chk_ncomp == 1);
261 
262  is >> chk_ncomp;
263  GotoNextLine(is);
264  AMREX_ASSERT(chk_ncomp == 2);
265 
266  is >> chk_ncomp;
267  GotoNextLine(is);
268  AMREX_ASSERT(chk_ncomp == 2);
269 
270  is >> chk_ncomp;
271  GotoNextLine(is);
272  AMREX_ASSERT(chk_ncomp == 3);
273 
274  is >> chk_ncomp;
275  GotoNextLine(is);
276  AMREX_ASSERT(chk_ncomp == 3);
277 
278  // read in array of istep
279  std::getline(is, line);
280  {
281  std::istringstream lis(line);
282  int i = 0;
283  while (lis >> word) {
284  istep[i++] = std::stoi(word);
285  }
286  }
287 
288  // read in array of dt
289  std::getline(is, line);
290  {
291  std::istringstream lis(line);
292  int i = 0;
293  while (lis >> word) {
294  dt[i++] = std::stod(word);
295  }
296  }
297 
298  // read in array of t_new
299  std::getline(is, line);
300  {
301  std::istringstream lis(line);
302  int i = 0;
303  while (lis >> word) {
304  t_new[i++] = std::stod(word);
305  }
306  }
307 
308  for (int lev = 0; lev <= finest_level; ++lev) {
309 
310  // read in level 'lev' BoxArray from Header
311  BoxArray ba;
312  ba.readFrom(is);
313  GotoNextLine(is);
314 
315  // create a distribution mapping
316  DistributionMapping dm { ba, ParallelDescriptor::NProcs() };
317 
318  MakeNewLevelFromScratch (lev, t_new[lev], ba, dm);
319  }
320 
321  // read in the MultiFab data
322  for (int lev = 0; lev <= finest_level; ++lev)
323  {
324  BoxList bl2d = grids[lev].boxList();
325  for (auto& b : bl2d) {
326  b.setRange(2,0);
327  }
328  BoxArray ba2d(std::move(bl2d));
329 
330  MultiFab cons(grids[lev],dmap[lev],NCONS,0);
331  VisMF::Read(cons, amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "Cell"));
332  MultiFab::Copy(*cons_new[lev],cons,0,0,NCONS,0);
333 
334  MultiFab xvel(convert(grids[lev],IntVect(1,0,0)),dmap[lev],1,0);
335  VisMF::Read(xvel, amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "XFace"));
336  MultiFab::Copy(*xvel_new[lev],xvel,0,0,1,0);
337 
338  MultiFab yvel(convert(grids[lev],IntVect(0,1,0)),dmap[lev],1,0);
339  VisMF::Read(yvel, amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "YFace"));
340  MultiFab::Copy(*yvel_new[lev],yvel,0,0,1,0);
341 
342  MultiFab zvel(convert(grids[lev],IntVect(0,0,1)),dmap[lev],1,0);
343  VisMF::Read(zvel, amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "ZFace"));
344  MultiFab::Copy(*zvel_new[lev],zvel,0,0,1,0);
345 
346  MultiFab mf_ru(grids[lev],dmap[lev],2,NGROW);
347  VisMF::Read(mf_ru, amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "XRHS"));
348  MultiFab::Copy(*(vec_ru[lev]),mf_ru,0,0,2,(vec_ru[lev])->nGrowVect());
349 
350  MultiFab mf_rv(grids[lev],dmap[lev],2,NGROW);
351  VisMF::Read(mf_rv, amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "YRHS"));
352  MultiFab::Copy(*(vec_rv[lev]),mf_rv,0,0,2,(vec_rv[lev])->nGrowVect());
353 
354  MultiFab mf_ubar(ba2d,dmap[lev],3,NGROW);
355  VisMF::Read(mf_ubar, amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "XBar"));
356  MultiFab::Copy(*(vec_ubar[lev]),mf_ubar,0,0,3,(vec_ubar[lev])->nGrowVect());
357 
358  MultiFab mf_vbar(ba2d,dmap[lev],3,NGROW);
359  VisMF::Read(mf_vbar, amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "YBar"));
360  MultiFab::Copy(*(vec_vbar[lev]),mf_vbar,0,0,3,(vec_vbar[lev])->nGrowVect());
361 
362  VisMF::Read(*(vec_rufrc[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "rufrc"));
363  VisMF::Read(*(vec_rvfrc[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "rvfrc"));
364 
365  VisMF::Read(*(vec_sustr[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "sustr"));
366  VisMF::Read(*(vec_svstr[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "svstr"));
367 
368  VisMF::Read(*(vec_rdrag[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "rdrag"));
369 
370  VisMF::Read(*(vec_bustr[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "bustr"));
371  VisMF::Read(*(vec_bvstr[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "bvstr"));
372 
373  VisMF::Read(*(vec_DU_avg1[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "DU_avg1"));
374  VisMF::Read(*(vec_DU_avg2[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "DU_avg2"));
375  VisMF::Read(*(vec_DV_avg1[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "DV_avg1"));
376  VisMF::Read(*(vec_DV_avg2[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "DV_avg2"));
377 
378  VisMF::Read(*(vec_zeta[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "zeta"));
379  VisMF::Read(*(vec_Zt_avg1[lev]), amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "Zt_avg1"));
380  }
381 
382 #ifdef REMORA_USE_PARTICLES
383  particleData.Restart((amrex::ParGDBBase*)GetParGDB(),restart_chkfile);
384 #endif
385 
386 #ifdef REMORA_USE_NETCDF
387  // Read bdy_data files
389  {
390  int ioproc = ParallelDescriptor::IOProcessorNumber(); // I/O rank
391  int num_time;
392  int num_var;
393  Vector<Box> bx_v;
394  if (ParallelDescriptor::IOProcessor()) {
395  // Open header file and read from it
396  std::ifstream bdy_h_file(amrex::MultiFabFileFullPrefix(0, restart_chkfile, "Level_", "bdy_H"));
397  bdy_h_file >> num_time;
398  bdy_h_file >> num_var;
399  bdy_h_file >> start_bdy_time;
400  bdy_h_file >> bdy_time_interval;
401  bdy_h_file >> bdy_width;
402  bx_v.resize(4*num_var);
403  for (int ivar(0); ivar<num_var; ++ivar) {
404  bdy_h_file >> bx_v[4*ivar ];
405  bdy_h_file >> bx_v[4*ivar+1];
406  bdy_h_file >> bx_v[4*ivar+2];
407  bdy_h_file >> bx_v[4*ivar+3];
408  }
409 
410  // IO size the FABs
411  bdy_data_xlo.resize(num_time);
412  bdy_data_xhi.resize(num_time);
413  bdy_data_ylo.resize(num_time);
414  bdy_data_yhi.resize(num_time);
415  for (int itime(0); itime<num_time; ++itime) {
416  bdy_data_xlo[itime].resize(num_var);
417  bdy_data_xhi[itime].resize(num_var);
418  bdy_data_ylo[itime].resize(num_var);
419  bdy_data_yhi[itime].resize(num_var);
420  for (int ivar(0); ivar<num_var; ++ivar) {
421  bdy_data_xlo[itime][ivar].resize(bx_v[4*ivar ]);
422  bdy_data_xhi[itime][ivar].resize(bx_v[4*ivar+1]);
423  bdy_data_ylo[itime][ivar].resize(bx_v[4*ivar+2]);
424  bdy_data_yhi[itime][ivar].resize(bx_v[4*ivar+3]);
425  }
426  }
427 
428  // Open data file and read from it
429  std::ifstream bdy_d_file(amrex::MultiFabFileFullPrefix(0, restart_chkfile, "Level_", "bdy_D"));
430  for (int itime(0); itime<num_time; ++itime) {
431  for (int ivar(0); ivar<num_var; ++ivar) {
432  bdy_data_xlo[itime][ivar].readFrom(bdy_d_file);
433  bdy_data_xhi[itime][ivar].readFrom(bdy_d_file);
434  bdy_data_ylo[itime][ivar].readFrom(bdy_d_file);
435  bdy_data_yhi[itime][ivar].readFrom(bdy_d_file);
436  }
437  }
438  } // IO
439 
440  // Broadcast the data
441  ParallelDescriptor::Barrier();
442  ParallelDescriptor::Bcast(&start_bdy_time,1,ioproc);
443  ParallelDescriptor::Bcast(&bdy_time_interval,1,ioproc);
444  ParallelDescriptor::Bcast(&bdy_width,1,ioproc);
445  ParallelDescriptor::Bcast(&num_time,1,ioproc);
446  ParallelDescriptor::Bcast(&num_var,1,ioproc);
447 
448  // Everyone size their boxes
449  bx_v.resize(4*num_var);
450 
451  ParallelDescriptor::Bcast(bx_v.dataPtr(),bx_v.size(),ioproc);
452 
453  // Everyone but IO size their FABs
454  if (!ParallelDescriptor::IOProcessor()) {
455  bdy_data_xlo.resize(num_time);
456  bdy_data_xhi.resize(num_time);
457  bdy_data_ylo.resize(num_time);
458  bdy_data_yhi.resize(num_time);
459  for (int itime(0); itime<num_time; ++itime) {
460  bdy_data_xlo[itime].resize(num_var);
461  bdy_data_xhi[itime].resize(num_var);
462  bdy_data_ylo[itime].resize(num_var);
463  bdy_data_yhi[itime].resize(num_var);
464  for (int ivar(0); ivar<num_var; ++ivar) {
465  bdy_data_xlo[itime][ivar].resize(bx_v[4*ivar ]);
466  bdy_data_xhi[itime][ivar].resize(bx_v[4*ivar+1]);
467  bdy_data_ylo[itime][ivar].resize(bx_v[4*ivar+2]);
468  bdy_data_yhi[itime][ivar].resize(bx_v[4*ivar+3]);
469  }
470  }
471  }
472 
473  for (int itime(0); itime<num_time; ++itime) {
474  for (int ivar(0); ivar<num_var; ++ivar) {
475  ParallelDescriptor::Bcast(bdy_data_xlo[itime][ivar].dataPtr(),bdy_data_xlo[itime][ivar].box().numPts(),ioproc);
476  ParallelDescriptor::Bcast(bdy_data_xhi[itime][ivar].dataPtr(),bdy_data_xhi[itime][ivar].box().numPts(),ioproc);
477  ParallelDescriptor::Bcast(bdy_data_ylo[itime][ivar].dataPtr(),bdy_data_ylo[itime][ivar].box().numPts(),ioproc);
478  ParallelDescriptor::Bcast(bdy_data_yhi[itime][ivar].dataPtr(),bdy_data_yhi[itime][ivar].box().numPts(),ioproc);
479  }
480  }
481  } // init real
482 #endif
483 }
static void GotoNextLine(std::istream &is)
Definition: Checkpoint.cpp:8
virtual void MakeNewLevelFromScratch(int lev, amrex::Real time, const amrex::BoxArray &ba, const amrex::DistributionMapping &dm) override
Definition: REMORA_make_new_level.cpp:102

◆ ReadParameters()

void REMORA::ReadParameters ( )
private

read in some parameters from inputs file

485 {
486  {
487  ParmParse pp; // Traditionally, max_step and stop_time do not have prefix.
488  pp.query("max_step", max_step);
489  pp.query("stop_time", stop_time);
490  }
491 
492  ParmParse pp(pp_prefix);
493  {
494  pp.query("regrid_int", regrid_int);
495  pp.query("check_file", check_file);
496  pp.query("check_int", check_int);
497 
498  pp.query("restart", restart_chkfile);
499 
500  if (pp.contains("data_log"))
501  {
502  int num_datalogs = pp.countval("data_log");
503  datalog.resize(num_datalogs);
504  datalogname.resize(num_datalogs);
505  pp.queryarr("data_log",datalogname,0,num_datalogs);
506  for (int i = 0; i < num_datalogs; i++)
508  }
509 
510  // Verbosity
511  pp.query("v", verbose);
512 
513  // Frequency of diagnostic output
514  pp.query("sum_interval", sum_interval);
515  pp.query("sum_period" , sum_per);
516 
517  // Time step controls
518  pp.query("cfl", cfl);
519  pp.query("init_shrink", init_shrink);
520  pp.query("change_max", change_max);
521 
522  pp.query("fixed_dt", fixed_dt);
523  pp.query("fixed_fast_dt", fixed_fast_dt);
524 
525  pp.query("fixed_ndtfast_ratio", fixed_ndtfast_ratio);
526 
527  // If all three are specified, they must be consistent
528  if (fixed_dt > 0. && fixed_fast_dt > 0. && fixed_ndtfast_ratio > 0)
529  {
531  {
532  amrex::Abort("Dt is over-specfied");
533  }
534  }
535  // If two are specified, initialize fixed_ndtfast_ratio
536  else if (fixed_dt > 0. && fixed_fast_dt > 0. && fixed_ndtfast_ratio <= 0)
537  {
538  fixed_ndtfast_ratio = static_cast<int>(fixed_dt / fixed_fast_dt);
539  }
540 
541  pp.query("do_substep", do_substep);
542 
543  AMREX_ASSERT(cfl > 0. || fixed_dt > 0.);
544 
545  // We use this to keep track of how many boxes we read in from WRF initialization
546  num_files_at_level.resize(max_level+1,0);
547 
548  // We use this to keep track of how many boxes are specified thru the refinement indicators
549  num_boxes_at_level.resize(max_level+1,0);
550  boxes_at_level.resize(max_level+1);
551 
552  // We always have exactly one file at level 0
553  num_boxes_at_level[0] = 1;
554  boxes_at_level[0].resize(1);
555  boxes_at_level[0][0] = geom[0].Domain();
556 
557  // Output format
558  std::string plotfile_type_str = "amrex";
559  pp.query("plotfile_type", plotfile_type_str);
560  if (plotfile_type_str == "amrex") {
562  } else if (plotfile_type_str == "netcdf" || plotfile_type_str == "NetCDF") {
564 #ifdef REMORA_USE_NETCDF
565  pp.query("write_history_file",write_history_file);
566 #endif
567  } else {
568  amrex::Print() << "User selected plotfile_type = " << plotfile_type_str << std::endl;
569  amrex::Abort("Dont know this plotfile_type");
570  }
571 #ifndef REMORA_USE_NETCDF
573  {
574  amrex::Abort("Please compile with NetCDF in order to enable NetCDF plotfiles");
575  }
576 
577 #endif
578 
579 #ifdef REMORA_USE_NETCDF
580  nc_init_file.resize(max_level+1);
581  nc_grid_file.resize(max_level+1);
582 
583  // NetCDF initialization files -- possibly multiple files at each of multiple levels
584  // but we always have exactly one file at level 0
585  for (int lev = 0; lev <= max_level; lev++)
586  {
587  const std::string nc_file_names = amrex::Concatenate("nc_init_file_",lev,1);
588  const std::string nc_bathy_file_names = amrex::Concatenate("nc_grid_file_",lev,1);
589 
590  if (pp.contains(nc_file_names.c_str()))
591  {
592  int num_files = pp.countval(nc_file_names.c_str());
593  int num_bathy_files = pp.countval(nc_bathy_file_names.c_str());
594  if (num_files != num_bathy_files) {
595  amrex::Error("Must have same number of netcdf files for grid info as for solution");
596  }
597 
598  num_files_at_level[lev] = num_files;
599  nc_init_file[lev].resize(num_files);
600  nc_grid_file[lev].resize(num_files);
601 
602  pp.queryarr(nc_file_names.c_str() , nc_init_file[lev] ,0,num_files);
603  pp.queryarr(nc_bathy_file_names.c_str(), nc_grid_file[lev],0,num_files);
604  }
605  }
606  // We only read boundary data at level 0
607  pp.query("nc_bdry_file", nc_bdry_file);
608 
609  // Query the set and total widths for bdy interior ghost cells
610  pp.query("bdy_width", bdy_width);
611  pp.query("bdy_set_width", bdy_set_width);
612  AMREX_ALWAYS_ASSERT(bdy_width >= 0);
613  AMREX_ALWAYS_ASSERT(bdy_set_width >= 0);
614  AMREX_ALWAYS_ASSERT(bdy_width >= bdy_set_width);
615 #endif
616  pp.query("plot_file_1", plot_file_1);
617  pp.query("plot_file_2", plot_file_2);
618  pp.query("plot_int_1", plot_int_1);
619  pp.query("plot_int_2", plot_int_2);
620 
621 #ifdef REMORA_USE_PARTICLES
622  particleData.init_particle_params();
623 #endif
624  }
625 
627 }
static amrex::Real init_shrink
Definition: REMORA.H:783
amrex::Vector< amrex::Vector< amrex::Box > > boxes_at_level
Definition: REMORA.H:727
std::string check_file
Definition: REMORA.H:806
static amrex::Real fixed_fast_dt
Definition: REMORA.H:788
int regrid_int
Definition: REMORA.H:797
amrex::Vector< int > num_files_at_level
Definition: REMORA.H:726
std::string plot_file_2
Definition: REMORA.H:801
amrex::Vector< int > num_boxes_at_level
Definition: REMORA.H:725
std::string plot_file_1
Definition: REMORA.H:800
void setRecordDataInfo(int i, const std::string &filename)
Definition: REMORA.H:954
std::string pp_prefix
Definition: REMORA.H:181
static std::string nc_bdry_file
Definition: REMORA.H:846
static amrex::Vector< amrex::Vector< std::string > > nc_grid_file
Definition: REMORA.H:843
static amrex::Vector< amrex::Vector< std::string > > nc_init_file
Definition: REMORA.H:842
void init_params()
Definition: DataStruct.H:43

◆ refinement_criteria_setup()

void REMORA::refinement_criteria_setup ( )
private

Function to define the refinement criteria based on user input

40 {
41  if (max_level > 0)
42  {
43  ParmParse pp(pp_prefix);
44  Vector<std::string> refinement_indicators;
45  pp.queryarr("refinement_indicators",refinement_indicators,0,pp.countval("refinement_indicators"));
46 
47  for (int i=0; i<refinement_indicators.size(); ++i)
48  {
49  std::string ref_prefix = pp_prefix + "." + refinement_indicators[i];
50 
51  ParmParse ppr(ref_prefix);
52  RealBox realbox;
53  int lev_for_box;
54  if (ppr.countval("in_box_lo")) {
55  std::vector<Real> box_lo(3), box_hi(3);
56  ppr.get("max_level",lev_for_box);
57  if (lev_for_box <= max_level)
58  {
59  ppr.getarr("in_box_lo",box_lo,0,2);
60  ppr.getarr("in_box_hi",box_hi,0,2);
61  box_lo[2] = geom[0].ProbLo(2);
62  box_hi[2] = geom[0].ProbHi(2);
63  realbox = RealBox(&(box_lo[0]),&(box_hi[0]));
64 
65  amrex::Print() << "Reading " << realbox << " at level " << lev_for_box << std::endl;
66  num_boxes_at_level[lev_for_box] += 1;
67 
68  const auto* dx = geom[lev_for_box].CellSize();
69  const Real* plo = geom[lev_for_box].ProbLo();
70  int ilo = static_cast<int>((box_lo[0] - plo[0])/dx[0]);
71  int jlo = static_cast<int>((box_lo[1] - plo[1])/dx[1]);
72  int klo = static_cast<int>((box_lo[2] - plo[2])/dx[2]);
73  int ihi = static_cast<int>((box_hi[0] - plo[0])/dx[0]-1);
74  int jhi = static_cast<int>((box_hi[1] - plo[1])/dx[1]-1);
75  int khi = static_cast<int>((box_hi[2] - plo[2])/dx[2]-1);
76  Box bx(IntVect(ilo,jlo,klo),IntVect(ihi,jhi,khi));
77  if ( (ilo%ref_ratio[lev_for_box-1][0] != 0) || ((ihi+1)%ref_ratio[lev_for_box-1][0] != 0) ||
78  (jlo%ref_ratio[lev_for_box-1][1] != 0) || ((jhi+1)%ref_ratio[lev_for_box-1][1] != 0) )
79  amrex::Error("Fine box is not legit with this ref_ratio");
80  boxes_at_level[lev_for_box].push_back(bx);
81  amrex::Print() << "Saving in 'boxes at level' as " << bx << std::endl;
82  } // lev
83  }
84 
85  AMRErrorTagInfo info;
86 
87  if (realbox.ok()) {
88  info.SetRealBox(realbox);
89  }
90  if (ppr.countval("start_time") > 0) {
91  Real ref_min_time; ppr.get("start_time",ref_min_time);
92  info.SetMinTime(ref_min_time);
93  }
94  if (ppr.countval("end_time") > 0) {
95  Real ref_max_time; ppr.get("end_time",ref_max_time);
96  info.SetMaxTime(ref_max_time);
97  }
98  if (ppr.countval("max_level") > 0) {
99  int ref_max_level; ppr.get("max_level",ref_max_level);
100  info.SetMaxLevel(ref_max_level);
101  }
102 
103  if (ppr.countval("value_greater")) {
104  int num_val = ppr.countval("value_greater");
105  Vector<Real> value(num_val);
106  ppr.getarr("value_greater",value,0,num_val);
107  std::string field; ppr.get("field_name",field);
108  ref_tags.push_back(AMRErrorTag(value,AMRErrorTag::GREATER,field,info));
109  }
110  else if (ppr.countval("value_less")) {
111  int num_val = ppr.countval("value_less");
112  Vector<Real> value(num_val);
113  ppr.getarr("value_less",value,0,num_val);
114  std::string field; ppr.get("field_name",field);
115  ref_tags.push_back(AMRErrorTag(value,AMRErrorTag::LESS,field,info));
116  }
117  else if (ppr.countval("adjacent_difference_greater")) {
118  int num_val = ppr.countval("adjacent_difference_greater");
119  Vector<Real> value(num_val);
120  ppr.getarr("adjacent_difference_greater",value,0,num_val);
121  std::string field; ppr.get("field_name",field);
122  ref_tags.push_back(AMRErrorTag(value,AMRErrorTag::GRAD,field,info));
123  }
124  else if (realbox.ok())
125  {
126  ref_tags.push_back(AMRErrorTag(info));
127  } else {
128  Abort(std::string("Unrecognized refinement indicator for " + refinement_indicators[i]).c_str());
129  }
130  } // loop over criteria
131  } // if max_level > 0
132 }

◆ RemakeLevel()

void REMORA::RemakeLevel ( int  lev,
amrex::Real  time,
const amrex::BoxArray &  ba,
const amrex::DistributionMapping &  dm 
)
overridevirtual

Remake an existing level using provided BoxArray and DistributionMapping and fill with existing fine and coarse data. Overrides the pure virtual function in AmrCore

50 {
51 #if (NGROW==2)
52  int ngrow_state = ComputeGhostCells(solverChoice.spatial_order)+1;
53  int ngrow_vels = ComputeGhostCells(solverChoice.spatial_order)+1;
54 #else
55  int ngrow_state = ComputeGhostCells(solverChoice.spatial_order)+2;
56  int ngrow_vels = ComputeGhostCells(solverChoice.spatial_order)+2;
57 #endif
58 
59  MultiFab* tmp_cons_new; tmp_cons_new->define(ba, dm, NCONS, ngrow_state);
60  MultiFab* tmp_cons_old; tmp_cons_old->define(ba, dm, NCONS, ngrow_state);
61 
62  MultiFab* tmp_xvel_new; tmp_xvel_new->define(convert(ba, IntVect(1,0,0)), dm, 1, ngrow_vels);
63  MultiFab* tmp_xvel_old; tmp_xvel_old->define(convert(ba, IntVect(1,0,0)), dm, 1, ngrow_vels);
64 
65  MultiFab* tmp_yvel_new; tmp_yvel_new->define(convert(ba, IntVect(0,1,0)), dm, 1, ngrow_vels);
66  MultiFab* tmp_yvel_old; tmp_yvel_old->define(convert(ba, IntVect(0,1,0)), dm, 1, ngrow_vels);
67 
68  MultiFab* tmp_zvel_new; tmp_zvel_new->define(convert(ba, IntVect(0,0,1)), dm, 1, IntVect(ngrow_vels,ngrow_vels,0));
69  MultiFab* tmp_zvel_old; tmp_zvel_old->define(convert(ba, IntVect(0,0,1)), dm, 1, IntVect(ngrow_vels,ngrow_vels,0));
70 
71  // This will fill the temporary MultiFabs with data from previous fine data as well as coarse where needed
72  FillPatch(lev, time, *tmp_cons_new, cons_new, BdyVars::t);
73  FillPatch(lev, time, *tmp_xvel_new, xvel_new, BdyVars::u);
74  FillPatch(lev, time, *tmp_yvel_new, yvel_new, BdyVars::v);
75  FillPatch(lev, time, *tmp_zvel_new, zvel_new, BdyVars::null);
76 
77  MultiFab::Copy(*tmp_cons_old,*tmp_cons_new,0,0,NCONS,tmp_cons_new[lev].nGrowVect());
78  MultiFab::Copy(*tmp_xvel_old,*tmp_xvel_new,0,0, 1,tmp_xvel_new[lev].nGrowVect());
79  MultiFab::Copy(*tmp_yvel_old,*tmp_yvel_new,0,0, 1,tmp_yvel_new[lev].nGrowVect());
80  MultiFab::Copy(*tmp_zvel_old,*tmp_zvel_new,0,0, 1,tmp_zvel_new[lev].nGrowVect());
81 
82  std::swap(tmp_cons_new, cons_new[lev]);
83  std::swap(tmp_cons_old, cons_old[lev]);
84  std::swap(tmp_xvel_new, xvel_new[lev]);
85  std::swap(tmp_xvel_old, xvel_old[lev]);
86  std::swap(tmp_yvel_new, yvel_new[lev]);
87  std::swap(tmp_yvel_old, yvel_old[lev]);
88  std::swap(tmp_zvel_new, zvel_new[lev]);
89  std::swap(tmp_zvel_old, zvel_old[lev]);
90 
91  t_new[lev] = time;
92  t_old[lev] = time - 1.e200;
93 
94  init_stuff(lev, ba, dm);
95 }

◆ remora_advance()

void REMORA::remora_advance ( int  level,
amrex::MultiFab &  cons_old,
amrex::MultiFab &  cons_new,
amrex::MultiFab &  xvel_old,
amrex::MultiFab &  yvel_old,
amrex::MultiFab &  zvel_old,
amrex::MultiFab &  xvel_new,
amrex::MultiFab &  yvel_new,
amrex::MultiFab &  zvel_new,
amrex::MultiFab &  source,
const amrex::Geometry  fine_geom,
const amrex::Real  dt,
const amrex::Real  time 
)

Interface for advancing the data at one level by one "slow" timestep

◆ resize_stuff()

void REMORA::resize_stuff ( int  lev)
private
138 {
139  vec_z_phys_nd.resize(lev+1);
140 
141  vec_hOfTheConfusingName.resize(lev+1);
142  vec_Zt_avg1.resize(lev+1);
143  vec_s_r.resize(lev+1);
144  vec_z_w.resize(lev+1);
145  vec_z_r.resize(lev+1);
146  vec_y_r.resize(lev+1);
147  vec_x_r.resize(lev+1);
148  vec_Hz.resize(lev+1);
149  vec_Huon.resize(lev+1);
150  vec_Hvom.resize(lev+1);
151  vec_Akv.resize(lev+1);
152  vec_Akt.resize(lev+1);
153  vec_visc3d_r.resize(lev+1);
154  vec_visc2_p.resize(lev+1);
155  vec_visc2_r.resize(lev+1);
156  vec_diff2.resize(lev+1);
157  vec_ru.resize(lev+1);
158  vec_rv.resize(lev+1);
159  vec_rufrc.resize(lev+1);
160  vec_rvfrc.resize(lev+1);
161  vec_sustr.resize(lev+1);
162  vec_svstr.resize(lev+1);
163  vec_rdrag.resize(lev+1);
164  vec_bustr.resize(lev+1);
165  vec_bvstr.resize(lev+1);
166 
167  vec_DU_avg1.resize(lev+1);
168  vec_DU_avg2.resize(lev+1);
169  vec_DV_avg1.resize(lev+1);
170  vec_DV_avg2.resize(lev+1);
171  vec_rubar.resize(lev+1);
172  vec_rvbar.resize(lev+1);
173  vec_rzeta.resize(lev+1);
174  vec_ubar.resize(lev+1);
175  vec_vbar.resize(lev+1);
176  vec_zeta.resize(lev+1);
177  vec_sstore.resize(lev+1);
178 
179  vec_pm.resize(lev+1);
180  vec_pn.resize(lev+1);
181  vec_fcor.resize(lev+1);
182 
183  vec_rhoS.resize(lev+1);
184  vec_rhoA.resize(lev+1);
185 
186  mapfac_m.resize(lev+1);
187  mapfac_u.resize(lev+1);
188  mapfac_v.resize(lev+1);
189 }

◆ restart()

void REMORA::restart ( )

Restart

364 {
366 
367  // We set this here so that we don't over-write the checkpoint file we just started from
369 }
void ReadCheckpointFile()
Definition: Checkpoint.cpp:214

◆ rho_eos()

void REMORA::rho_eos ( const amrex::Box &  bx,
const amrex::Array4< amrex::Real const > &  state,
const amrex::Array4< amrex::Real > &  rho,
const amrex::Array4< amrex::Real > &  rhoA,
const amrex::Array4< amrex::Real > &  rhoS,
const amrex::Array4< amrex::Real const > &  Hz,
const amrex::Array4< amrex::Real const > &  z_w,
const amrex::Array4< amrex::Real const > &  h,
const int  N 
)

rho_eos

Parameters
[in]bxbox for calculation
[in]statestate holds temp, salt
[out]rhodensity
[out]rhoAvertically-averaged density
[out]rhoSdensity perturbation
[in]Hz
[in]z_w
[in]h
[in]N
29 {
30 //
31  AMREX_ASSERT(bx.smallEnd(2) == 0 && bx.bigEnd(2) == N);
32 //
33 //=======================================================================
34 // Linear equation of state.
35 //=======================================================================
36 //
37 //
38 //-----------------------------------------------------------------------
39 // Compute "in situ" density anomaly (kg/m3 - 1000) using the linear
40 // equation of state.
41 //-----------------------------------------------------------------------
42 //
43  Real R0 = solverChoice.R0;
44  Real S0 = solverChoice.S0;
45  Real T0 = solverChoice.T0;
46  Real Tcoef = solverChoice.Tcoef;
47  Real Scoef = solverChoice.Scoef;
48 
49  ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
50  {
51  rho(i,j,k) = R0 - R0*Tcoef*(state(i,j,k,Temp_comp)-T0)
52  + R0*Scoef*(state(i,j,k,Salt_comp)-S0)
53  - 1000.0_rt;
54  });
55 
56 //
57 //-----------------------------------------------------------------------
58 // Compute vertical averaged density (rhoA) and density perturbation
59 // used (rhoS) in barotropic pressure gradient.
60 //-----------------------------------------------------------------------
61 //
62  Real cff2 =1.0_rt/solverChoice.rho0;
63 
64  ParallelFor(makeSlab(bx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
65  {
66  Real cff0 = rho(i,j,N)*Hz(i,j,N);
67  rhoS(i,j,0) = 0.5_rt*cff0*Hz(i,j,N);
68  rhoA(i,j,0) = cff0;
69 
70  for (int k = 1; k <= N; ++k) {
71  Real cff1=rho(i,j,N-k)*Hz(i,j,N-k);
72  rhoS(i,j,0) += Hz(i,j,N-k)*(rhoA(i,j,0)+0.5_rt*cff1);
73  rhoA(i,j,0) += cff1;
74  }
75 
76  Real cff11 =1.0_rt/(z_w(i,j,N)+h(i,j,0,0));
77 
78  rhoA(i,j,0) *= cff2*cff11;
79 
80  rhoS(i,j,0) *= 2.0_rt*cff11*cff11*cff2;
81  });
82 }
amrex::Real Tcoef
Definition: DataStruct.H:225
amrex::Real R0
Definition: DataStruct.H:222
amrex::Real T0
Definition: DataStruct.H:224
amrex::Real Scoef
Definition: DataStruct.H:226
amrex::Real S0
Definition: DataStruct.H:223

◆ rhs_t_3d()

void REMORA::rhs_t_3d ( const amrex::Box &  bx,
const amrex::Box &  gbx,
const amrex::Array4< amrex::Real > &  t,
const amrex::Array4< amrex::Real const > &  tempstore,
const amrex::Array4< amrex::Real const > &  Huon,
const amrex::Array4< amrex::Real const > &  Hvom,
const amrex::Array4< amrex::Real const > &  Hz,
const amrex::Array4< amrex::Real const > &  pn,
const amrex::Array4< amrex::Real const > &  pm,
const amrex::Array4< amrex::Real const > &  W,
const amrex::Array4< amrex::Real > &  FC,
int  nrhs,
int  nnew,
int  N,
const amrex::Real  dt_lev 
)

rhs_t_3d

Parameters
[in]gbx
[in,out]t
[in]sstore
[in]Huon
[in]Hvom
[in]Hz
[in]pn
[in]pm
[in]W
[in,out]FC
[in]nrhs
[in]nnew
[in]N
[in]dt_lev
36 {
37  //copy the tilebox
38  Box tbxp1 = bx;
39  Box tbxp2 = bx;
40 
41  //make only gbx be grown to match multifabs
42  tbxp2.grow(IntVect(NGROW,NGROW,0));
43  tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
44 
45  // Because grad, curv, FX, FE, are all local, do surroundinNodes
46  Box utbxp1 = surroundingNodes(tbxp1, 0);
47  Box vtbxp1 = surroundingNodes(tbxp1, 1);
48  Box ubx = surroundingNodes(bx, 0);
49  Box vbx = surroundingNodes(bx, 1);
50 
51  BoxArray ba_gbx1 = intersect(BoxArray(tbxp1),gbx);
52  AMREX_ASSERT((ba_gbx1.size() == 1));
53 
54  //
55  // Scratch space
56  //
57  FArrayBox fab_grad(tbxp2,1,amrex::The_Async_Arena());
58  FArrayBox fab_curv(tbxp2,1,amrex::The_Async_Arena());
59 
60  FArrayBox fab_FX(tbxp2,1,amrex::The_Async_Arena());
61  FArrayBox fab_FE(tbxp2,1,amrex::The_Async_Arena());
62 
63  auto curv=fab_curv.array();
64  auto grad=fab_grad.array();
65 
66  auto FX=fab_FX.array();
67  auto FE=fab_FE.array();
68 
69  fab_grad.template setVal<RunOn::Device>(0.);
70  fab_curv.template setVal<RunOn::Device>(0.);
71 
72  fab_FX.template setVal<RunOn::Device>(0.);
73  fab_FE.template setVal<RunOn::Device>(0.);
74 
75  ParallelFor(utbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
76  {
77  //should be t index 3
78  FX(i,j,k)=sstore(i,j,k,nrhs)-sstore(i-1,j,k,nrhs);
79  });
80 
81  Real cffa=1.0_rt/6.0_rt;
82  Real cffb=1.0_rt/3.0_rt;
83 
85 
87 
88  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
89  {
90  //Upstream3
91  curv(i,j,k)=-FX(i,j,k)+FX(i+1,j,k);
92  });
93 
94  ParallelFor(ubx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
95  {
96  Real max_Huon = std::max(Huon(i,j,k),0.0_rt);
97  Real min_Huon = std::min(Huon(i,j,k),0.0_rt);
98  FX(i,j,k)=Huon(i,j,k)*0.5*(sstore(i,j,k)+sstore(i-1,j,k))+
99  cffa*(curv(i,j,k)*min_Huon+ curv(i-1,j,k)*max_Huon);
100  });
101 
103 
104  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
105  {
106  //Centered4
107  grad(i,j,k)=0.5*(FX(i,j,k)+FX(i+1,j,k));
108  });
109 
110  ParallelFor(ubx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
111  {
112  FX(i,j,k)=Huon(i,j,k)*0.5*(sstore(i,j,k)+sstore(i-1,j,k))+
113  cffb*(grad(i,j,k)+ grad(i-1,j,k));
114  });
115 
116  } else {
117  Error("Not a valid horizontal advection scheme");
118  }
119 
120  } else {
121 
123 
124  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
125  {
126  //Upstream3
127  curv(i,j,k)=-FX(i,j,k)+FX(i+1,j,k);
128  });
129 
130  //HACK to avoid using the wrong index of t (using upstream3)
131  ParallelFor(ubx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
132  {
133  Real max_Huon = std::max(Huon(i,j,k),0.0_rt);
134  Real min_Huon = std::min(Huon(i,j,k),0.0_rt);
135  FX(i,j,k)=Huon(i,j,k)*0.5*(sstore(i,j,k)+sstore(i-1,j,k))-
136  cffa*(curv(i,j,k)*min_Huon+ curv(i-1,j,k)*max_Huon);
137  });
138 
140 
141  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
142  {
143  //Centered4
144  grad(i,j,k)=0.5*(FX(i,j,k)+FX(i+1,j,k));
145  });
146 
147  ParallelFor(ubx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
148  {
149  FX(i,j,k)=Huon(i,j,k)*0.5*(sstore(i,j,k)+sstore(i-1,j,k)-
150  cffb*(grad(i,j,k)- grad(i-1,j,k)));
151  });
152 
153  } else {
154  Error("Not a valid horizontal advection scheme");
155  }
156  } // flat bathymetry?
157 
158  ParallelFor(vtbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
159  {
160  //should be t index 3
161  FE(i,j,k)=sstore(i,j,k,nrhs)-sstore(i,j-1,k,nrhs);
162  });
163 
164  cffa=1.0_rt/6.0_rt;
165  cffb=1.0_rt/3.0_rt;
167 
169 
170  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
171  {
172  curv(i,j,k)=-FE(i,j,k)+FE(i,j+1,k);
173  });
174 
175  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
176  {
177  Real max_Hvom = std::max(Hvom(i,j,k),0.0_rt);
178  Real min_Hvom = std::min(Hvom(i,j,k),0.0_rt);
179 
180  FE(i,j,k)=Hvom(i,j,k)*0.5*(sstore(i,j,k)+sstore(i,j-1,k))+
181  cffa*(curv(i,j,k)*min_Hvom+ curv(i,j-1,k)*max_Hvom);
182  });
183 
185 
186  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
187  {
188  grad(i,j,k)=0.5*(FE(i,j,k)+FE(i,j+1,k));
189  });
190 
191  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
192  {
193  FE(i,j,k)=Hvom(i,j,k)*0.5*(sstore(i,j,k)+sstore(i,j-1,k))+
194  cffb*(grad(i,j,k)+ grad(i,j-1,k));
195  });
196 
197  } else {
198  Error("Not a valid horizontal advection scheme");
199  }
200 
201  } else {
202 
204  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
205  {
206  curv(i,j,k)=-FE(i,j,k)+FE(i,j+1,k);
207  });
208 
209 
210  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
211  {
212  Real max_Hvom = std::max(Hvom(i,j,k),0.0_rt);
213  Real min_Hvom = std::min(Hvom(i,j,k),0.0_rt);
214 
215  FE(i,j,k)=Hvom(i,j,k)*0.5*(sstore(i,j,k)+sstore(i,j-1,k))-
216  cffa*(curv(i,j,k)*min_Hvom+ curv(i,j-1,k)*max_Hvom);
217  });
218 
220 
221  ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (int i, int j, int k)
222  {
223  grad(i,j,k)=0.5*(FE(i,j,k)+FE(i,j+1,k));
224  });
225 
226  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
227  {
228  FE(i,j,k)=Hvom(i,j,k)*0.5*(sstore(i,j,k)+sstore(i,j-1,k)-
229  cffb*(grad(i,j,k)- grad(i,j-1,k)));
230  });
231 
232  } else {
233  Error("Not a valid horizontal advection scheme");
234  }
235  }
236 
237  ParallelFor(bx,
238  [=] AMREX_GPU_DEVICE (int i, int j, int k)
239  {
240  //
241  // Add in horizontal advection.
242  //
243  Real cff = dt_lev*pm(i,j,0)*pn(i,j,0);
244  Real cff1=cff*(FX(i+1,j,k)-FX(i,j,k));
245  Real cff2=cff*(FE(i,j+1,k)-FE(i,j,k));
246  Real cff3=cff1+cff2;
247 
248  t(i,j,k,nnew) -= cff3;
249  });
250 
251  //-----------------------------------------------------------------------
252  // Time-step vertical advection term.
253  //-----------------------------------------------------------------------
254  //Check which type of differences:
255  //
256  // Fourth-order, central differences vertical advective flux
257  // (Tunits m3/s).
258  //
259 
260  ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
261  {
262  //-----------------------------------------------------------------------
263  // Add in vertical advection.
264  //-----------------------------------------------------------------------
265 
266  Real cff1=0.5_rt;
267  Real cff2=7.0_rt/12.0_rt;
268  Real cff3=1.0_rt/12.0_rt;
269 
270  if (k>=1 && k<=N-2)
271  {
272  FC(i,j,k)=( cff2*(sstore(i ,j,k )+ sstore(i,j,k+1))
273  -cff3*(sstore(i ,j,k-1)+ sstore(i,j,k+2)) ) * ( W(i,j,k));
274 
275  } else {
276 
277  FC(i,j,N)=0.0_rt;
278 
279  FC(i,j,N-1)=( cff2*sstore(i ,j,N-1)+ cff1*sstore(i,j,N )
280  -cff3*sstore(i ,j,N-2) ) * ( W(i ,j,N-1));
281 
282  FC(i,j,0)=( cff2*sstore(i ,j,1)+ cff1*sstore(i,j,0)
283  -cff3*sstore(i ,j,2) ) * ( W(i ,j,0));
284  }
285 
286  });
287 
288  ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
289  {
290  Real cff1=dt_lev*pm(i,j,0)*pn(i,j,0);
291  Real cff4;
292  if(k-1>=0) {
293  cff4=FC(i,j,k)-FC(i,j,k-1);
294  } else {
295  cff4=FC(i,j,k);
296  }
297 
298  t(i,j,k) = (t(i,j,k)-cff1*cff4) / Hz(i,j,k);
299  });
300 }

◆ rhs_uv_2d()

void REMORA::rhs_uv_2d ( const amrex::Box &  xbx,
const amrex::Box &  ybx,
const amrex::Array4< amrex::Real const > &  uold,
const amrex::Array4< amrex::Real const > &  vold,
const amrex::Array4< amrex::Real > &  ru,
const amrex::Array4< amrex::Real > &  rv,
const amrex::Array4< amrex::Real const > &  Duon,
const amrex::Array4< amrex::Real const > &  Dvom,
const int  nrhs 
)

rhs_uv_2d

Parameters
[in]xbxBox for operations on x-velocity
[in]ybxBox for operations on y-velocity
[in]ubar
[in]vbar
[out]rhs_ubar
[out]rhs_vbar
[in]DUon
[in]DVom
[in]krhs
28 {
29  //
30  // Scratch space
31  //
32  FArrayBox fab_UFx(growLo(xbx,0,1),1,amrex::The_Async_Arena()); fab_UFx.template setVal<RunOn::Device>(0.);
33  FArrayBox fab_UFe(growHi(xbx,1,1),1,amrex::The_Async_Arena()); fab_UFe.template setVal<RunOn::Device>(0.);
34  FArrayBox fab_VFe(growLo(ybx,1,1),1,amrex::The_Async_Arena()); fab_VFe.template setVal<RunOn::Device>(0.);
35  FArrayBox fab_VFx(growHi(ybx,0,1),1,amrex::The_Async_Arena()); fab_VFx.template setVal<RunOn::Device>(0.);
36 
37  auto UFx=fab_UFx.array();
38  auto UFe=fab_UFe.array();
39  auto VFx=fab_VFx.array();
40  auto VFe=fab_VFe.array();
41 
42  // *************************************************************
43  // UPDATING U
44  // *************************************************************
45 
46  // Think of the cell-centered box as [ 0:nx-1, 0:ny-1] (0,0,0) cc
47  //
48  // xbx is the x-face-centered box on which we update ubar (with rhs_ubar) [ 0:nx , 0:ny-1] (1,0,0) x-faces
49  // to do so requires UFx on [-1:nx , 0:ny-1] (0,0,0) cc
50  // which requires ubar on [-2:nx+2, 0:ny-1] (1,0,0) x-faces
51  // and requires DUon on [-2:nx+2, 0:ny-1] (1,0,0) x-faces
52  // to do so requires UFe on [ 0:nx , 0:ny ] (1,1,0) xy-nodes
53  // which requires ubar on [ 0:nx ,-2:ny+1] (1,0,0) x-faces
54  // and requires DVom on [-2:nx+1, 0:ny-1] (0,1,0) y-faces
55 
56  //
57  // Define UFx, the x-fluxes at cell centers for updating u
58  // (Note that grow arguments are (bx, dir, ng)
59  //
60  ParallelFor(growLo(xbx,0,1),
61  [=] AMREX_GPU_DEVICE (int i, int j, int )
62  {
63  Real uxx_i = ubar(i-1,j,0,krhs)-2.0*ubar(i ,j,0,krhs)+ubar(i+1,j,0,krhs);
64  Real uxx_ip1 = ubar(i ,j,0,krhs)-2.0*ubar(i+1,j,0,krhs)+ubar(i+2,j,0,krhs);
65  Real uxx_avg = uxx_i + uxx_ip1;
66 
67  Real Huxx_i = DUon(i-1,j,0)-2.0*DUon(i ,j,0)+DUon(i+1,j,0);
68  Real Huxx_ip1 = DUon(i ,j,0)-2.0*DUon(i+1,j,0)+DUon(i+2,j,0);
69 
70  Real cff=1.0/6.0;
71  Real ubar_avg = ubar(i ,j,0,krhs)+ubar(i+1,j,0,krhs);
72 
73  UFx(i,j,0)=0.25*(ubar_avg-cff*uxx_avg) * (DUon(i,j,0)+ DUon(i+1,j,0)-cff*(Huxx_i+ Huxx_ip1));
74  });
75 
76  //
77  // Define UFe, the y-fluxes at nodes for updating u
78  //
79  ParallelFor(growHi(xbx,1,1),
80  [=] AMREX_GPU_DEVICE (int i, int j, int )
81  {
82  //should not include grow cells
83  Real uee_j = ubar(i,j-1,0,krhs)-2.0*ubar(i,j ,0,krhs)+ubar(i,j+1,0,krhs);
84  Real uee_jm1 = ubar(i,j-2,0,krhs)-2.0*ubar(i,j-1,0,krhs)+ubar(i,j ,0,krhs);
85  Real uee_avg = uee_j + uee_jm1;
86 
87  Real Hvxx_i = DVom(i-1,j,0)-2.0*DVom(i ,j,0)+DVom(i+1,j,0);
88  Real Hvxx_im1 = DVom(i-2,j,0)-2.0*DVom(i-1,j,0)+DVom(i ,j,0);
89  Real cff=1.0/6.0;
90  Real cff1=ubar(i,j ,0,krhs)+ubar(i,j-1,0,krhs);
91  Real cff2=DVom(i,j,0)+DVom(i-1,j,0);
92 
93  UFe(i,j,0)=0.25*(cff1-uee_avg*cff)*
94  (cff2-cff*(Hvxx_i+Hvxx_im1));
95  });
96 
97  //
98  // Add in horizontal advection.
99  //
100  ParallelFor(makeSlab(xbx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
101  {
102  Real cff1=UFx(i,j ,0)-UFx(i-1,j,0);
103  Real cff2=UFe(i,j+1,0)-UFe(i ,j,0);
104 
105  rhs_ubar(i,j,0) -= (cff1 + cff2);
106  });
107 
108  // *************************************************************
109  // UPDATING V
110  // *************************************************************
111 
112  // Think of the cell-centered box as [ 0:nx-1, 0:ny-1] (0,0,0) cc
113  //
114  // ybx is the y-face-centered box on which we update vbar (with rhs_vbar) [ 0:nx-1, 0:ny ] (1,0,0) y-faces
115  // to do so requires VFe on [ 0:nx-1,-1:ny ] (1,1,0) xy-nodes
116  // which requires vbar on [ 0:nx-1,-2:ny+2] (1,0,0) y-faces
117  // and requires DVom on [ 0:nx-1,-2:ny+2] (0,1,0) x-faces
118  // to do so requires VFx on [ 0:nx , 0:ny ] (0,0,0) cc
119  // which requires vbar on [-2:nx+1, 0:ny ] (1,0,0) y-faces
120  // and requires DUon on [ 0:nx-1,-2:ny+1] (0,0,0) y-faces
121 
122  // Grow ybx by one in high x-direction
123  ParallelFor(growHi(ybx,0,1),
124  [=] AMREX_GPU_DEVICE (int i, int j, int )
125  {
126  Real cff=1.0/6.0;
127  Real vxx_i = vbar(i-1,j,0,krhs)-2.0*vbar(i ,j,0,krhs)+vbar(i+1,j,0,krhs);
128  Real vxx_im1 = vbar(i-2,j,0,krhs)-2.0*vbar(i-1,j,0,krhs)+vbar(i ,j,0,krhs);
129  Real vxx_avg = vxx_i + vxx_im1;
130  //auto vxx_im1 = (i == gbx1.smallEnd(0)) ? vxx(i-1,j,k) :
131  // (vbar(i-2,j,0,krhs)-2.0*vbar(i-1,j,0,krhs)+vbar(i,j,0,krhs));
132  //neglecting terms about periodicity since testing only periodic for now
133  Real Huee_j = DUon(i,j-1,0)-2.0*DUon(i,j ,0)+DUon(i,j+1,0);
134  Real Huee_jm1 = DUon(i,j-2,0)-2.0*DUon(i,j-1,0)+DUon(i,j ,0);
135  Real cff1=vbar(i ,j,0,krhs)+vbar(i-1,j,0,krhs);
136  Real cff2=DUon(i,j,0)+DUon(i,j-1,0);
137 
138  //auto Huee_jm1 = (j == gbx1.smallEnd(1)) ? Huee(i,j-1,k) :
139  // (DUon(i,j-2,k)-2.0*DUon(i,j-1,k)+DUon(i,j,k));
140 
141  VFx(i,j,0)=0.25*(cff1-vxx_avg*cff)* (cff2-cff*(Huee_j+ Huee_jm1));
142  });
143 
144  ParallelFor(growLo(ybx,1,1),
145  [=] AMREX_GPU_DEVICE (int i, int j, int)
146  {
147  Real vee_j = vbar(i,j-1,0,krhs)-2.0*vbar(i,j ,0,krhs)+vbar(i,j+1,0,krhs);
148  Real vee_jp1 = vbar(i,j ,0,krhs)-2.0*vbar(i,j+1,0,krhs)+vbar(i,j+2,0,krhs);
149  Real vee_avg = vee_j + vee_jp1;
150 
151  Real Hvee_j = DVom(i,j-1,0)-2.0*DVom(i,j ,0)+DVom(i,j+1,0);
152  Real Hvee_jp1 = DVom(i,j ,0)-2.0*DVom(i,j+1,0)+DVom(i,j+2,0);
153 
154  Real cff=1.0/6.0;
155  Real cff1=vbar(i,j ,0,krhs)+vbar(i,j+1,0,krhs);
156 
157  VFe(i,j,0) = 0.25 * (cff1-vee_avg*cff) * (DVom(i,j ,0)+ DVom(i,j+1,0) -
158  cff * (Hvee_j+ Hvee_jp1));
159  });
160 
161  ParallelFor(makeSlab(ybx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
162  {
163  Real cff1=VFx(i+1,j,0)-VFx(i ,j,0);
164  Real cff2=VFe(i ,j,0)-VFe(i,j-1,0);
165 
166  rhs_vbar(i,j,0) -= (cff1 + cff2);
167  });
168 
169 }

◆ rhs_uv_3d()

void REMORA::rhs_uv_3d ( const amrex::Box &  xbx,
const amrex::Box &  ybx,
const amrex::Array4< amrex::Real const > &  uold,
const amrex::Array4< amrex::Real const > &  vold,
const amrex::Array4< amrex::Real > &  ru,
const amrex::Array4< amrex::Real > &  rv,
const amrex::Array4< amrex::Real > &  rufrc,
const amrex::Array4< amrex::Real > &  rvfrc,
const amrex::Array4< amrex::Real const > &  sustr,
const amrex::Array4< amrex::Real const > &  svstr,
const amrex::Array4< amrex::Real const > &  bustr,
const amrex::Array4< amrex::Real const > &  bvstr,
const amrex::Array4< amrex::Real const > &  Huon,
const amrex::Array4< amrex::Real const > &  Hvom,
const amrex::Array4< amrex::Real const > &  pm,
const amrex::Array4< amrex::Real const > &  pn,
const amrex::Array4< amrex::Real const > &  W,
const amrex::Array4< amrex::Real > &  FC,
int  nrhs,
int  N 
)

Calculation of the RHS

rhs_uv_2d

Parameters
[in]xbxBox for operations on x-velocity
[in]ybxBox for operations on y-velocity
[in]uold
[in]vold
[out]ru
[out]rv
[out]rufrc
[out]rvfrc
[in]sustr
[in]svstr
[in]bustr
[in]bvstr
[in]Huon
[in]Hvom
[in]pm
[in]pn
[in]W
[in,out]FC
[in]nrhs
[in]N
49 {
50  //
51  // Scratch space
52  //
53  FArrayBox fab_UFx(growLo(xbx,0,1),1,amrex::The_Async_Arena()); fab_UFx.template setVal<RunOn::Device>(0.);
54  FArrayBox fab_UFe(growHi(xbx,1,1),1,amrex::The_Async_Arena()); fab_UFe.template setVal<RunOn::Device>(0.);
55  FArrayBox fab_VFe(growLo(ybx,1,1),1,amrex::The_Async_Arena()); fab_VFe.template setVal<RunOn::Device>(0.);
56  FArrayBox fab_VFx(growHi(ybx,0,1),1,amrex::The_Async_Arena()); fab_VFx.template setVal<RunOn::Device>(0.);
57 
58  auto UFx=fab_UFx.array();
59  auto UFe=fab_UFe.array();
60  auto VFx=fab_VFx.array();
61  auto VFe=fab_VFe.array();
62 
63  //check this////////////
64  const Real Gadv = -0.25;
65 
66  // *************************************************************
67  // UPDATING U
68  // *************************************************************
69 
70  // Think of the cell-centered box as [ 0:nx-1, 0:ny-1] (0,0,0) cc
71  //
72  // xbx is the x-face-centered box on which we update u (with ru) [ 0:nx , 0:ny-1] (1,0,0) x-faces
73  // to do so requires UFx on [-1:nx , 0:ny-1] (0,0,0) cc
74  // which requires uold on [-2:nx+2, 0:ny-1] (1,0,0) x-faces
75  // and requires Huon on [-2:nx+2, 0:ny-1] (0,0,0) x-faces
76  // to do so requires UFe on [ 0:nx , 0:ny ] (1,1,0) xy-nodes
77  // which requires uold on [ 0:nx ,-2:ny+1] (1,0,0) x-faces
78  // and requires Hvom on [-2:nx+1, 0:ny-1] (0,1,0) y-faces
79 
80  //
81  // Define UFx, the x-fluxes at cell centers for updating u
82  // (Note that grow arguments are (bx, dir, ng)
83  //
84  ParallelFor(growLo(xbx,0,1), [=] AMREX_GPU_DEVICE (int i, int j, int k)
85  {
86  Real cff1 = uold(i,j,k,nrhs)+uold(i+1,j,k,nrhs);
87 
88  // Upwinding
89  Real cff = (cff1 > 0.0) ? uold(i-1,j,k,nrhs)-2.0*uold(i ,j,k,nrhs)+uold(i+1,j,k,nrhs) :
90  uold(i ,j,k,nrhs)-2.0*uold(i+1,j,k,nrhs)+uold(i+2,j,k,nrhs);
91 
92  Real Huxx_i = Huon(i-1,j,k)-2.0*Huon(i ,j,k)+Huon(i+1,j,k);
93  Real Huxx_ip1 = Huon(i ,j,k)-2.0*Huon(i+1,j,k)+Huon(i+2,j,k);
94  Real Huxx_avg = 0.5 * (Huxx_i + Huxx_ip1);
95 
96  Real Huon_avg = (Huon(i,j,k) + Huon(i+1,j,k));
97 
98  UFx(i,j,k) = 0.25*(cff1+Gadv*cff) * ( Huon_avg + Gadv*Huxx_avg );
99  });
100 
101  //
102  // Define UFe, the y-fluxes at nodes for updating u
103  //
104  ParallelFor(growHi(xbx,1,1), [=] AMREX_GPU_DEVICE (int i, int j, int k)
105  {
106  Real cff1 = uold(i,j,k,nrhs) + uold(i ,j-1,k,nrhs);
107  Real cff2 = Hvom(i,j,k) + Hvom(i-1,j ,k);
108 
109  // Upwinding
110  Real cff = (cff2 > 0.0) ? uold(i,j-2,k,nrhs) - 2.0*uold(i,j-1,k,nrhs) + uold(i ,j,k,nrhs) :
111  uold(i,j-1,k,nrhs) - 2.0*uold(i,j ,k,nrhs) + uold(i,j+1,k,nrhs);
112 
113  Real Hvxx_i = Hvom(i-1,j,k)-2.0*Hvom(i ,j,k)+Hvom(i+1,j,k);
114  Real Hvxx_im1 = Hvom(i-2,j,k)-2.0*Hvom(i-1,j,k)+Hvom(i ,j,k);
115 
116  UFe(i,j,k) = 0.25 * (cff1+Gadv*cff)* (cff2+Gadv*0.5*(Hvxx_i + Hvxx_im1));
117  });
118 
119  //
120  // Define the RHS for u by differencing fluxes
121  //
122  ParallelFor(xbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
123  {
124  ru(i,j,k,nrhs) -= ( (UFx(i,j,k)-UFx(i-1,j,k)) + (UFe(i,j+1,k)-UFe(i ,j,k)) );
125  });
126 
127  ParallelFor(xbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
128  {
129  //-----------------------------------------------------------------------
130  // Add in vertical advection.
131  //-----------------------------------------------------------------------
132  Real cff1=9.0/16.0;
133  Real cff2=1.0/16.0;
134 
135  if (k>=1 && k<=N-2)
136  {
137  FC(i,j,k)=( cff1*(uold(i ,j,k ,nrhs)+ uold(i,j,k+1,nrhs))
138  -cff2*(uold(i ,j,k-1,nrhs)+ uold(i,j,k+2,nrhs)) )*
139  ( cff1*( W(i ,j,k)+ W(i-1,j,k))
140  -cff2*( W(i+1,j,k)+ W(i-2,j,k)) );
141  }
142  else // this needs to be split up so that the following can be concurrent
143  {
144  FC(i,j,N)=0.0;
145 
146  FC(i,j,N-1)=( cff1*(uold(i ,j,N-1,nrhs)+ uold(i,j,N ,nrhs))
147  -cff2*(uold(i ,j,N-2,nrhs)+ uold(i,j,N ,nrhs)) )*
148  ( cff1*( W(i ,j,N-1)+ W(i-1,j,N-1))
149  -cff2*( W(i+1,j,N-1)+ W(i-2,j,N-1)) );
150 
151  FC(i,j,0)=( cff1*(uold(i ,j,0,nrhs)+ uold(i,j,1,nrhs))
152  -cff2*(uold(i ,j,0,nrhs)+ uold(i,j,2,nrhs)) )*
153  ( cff1*( W(i ,j,0)+ W(i-1,j,0))
154  -cff2*( W(i+1,j,0)+ W(i-2,j,0)) );
155 
156  // FC(i,0,-1)=0.0;
157  }
158  });
159 
160  ParallelFor(xbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
161  {
162  Real cff = (k >= 1) ? FC(i,j,k)-FC(i,j,k-1) : FC(i,j,k);
163 
164  ru(i,j,k,nrhs) -= cff;
165  });
166 
167  Gpu::synchronize();
168 
169  AMREX_ASSERT(xbx.smallEnd(2) == 0 && xbx.bigEnd(2) == N);
170  ParallelFor(makeSlab(xbx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
171  {
172  for (int k = 0; k <= N; ++k)
173  {
174  rufrc(i,j,0) += ru(i,j,k,nrhs);
175 
176  Real om_u = 2.0 / (pm(i-1,j,0)+pm(i,j,0));
177  Real on_u = 2.0 / (pn(i-1,j,0)+pn(i,j,0));
178  Real cff = om_u * on_u;
179 
180  Real cff1 = (k == N) ? sustr(i,j,0)*cff : 0.0;
181  Real cff2 = (k == 0) ? -bustr(i,j,0)*cff : 0.0;
182 
183  rufrc(i,j,0) += cff1+cff2;
184  }
185  });
186 
187  // *************************************************************
188  // UPDATING V
189  // *************************************************************
190 
191  // Think of the cell-centered box as [ 0:nx-1, 0:ny-1] (0,0,0) cc
192  //
193  // ybx is the y-face-centered box on which we update v (with rv) [ 0:nx-1, 0:ny ] (1,0,0) y-faces
194  // to do so requires VFe on [ 0:nx-1,-1:ny ] (1,1,0) xy-nodes
195  // which requires vold on [ 0:nx-1,-2:ny+2] (1,0,0) y-faces
196  // and requires Hvom on [ 0:nx-1,-2:ny+2] (0,1,0) x-faces
197  // to do so requires VFx on [ 0:nx , 0:ny ] (0,0,0) cc
198  // which requires vold on [-2:nx+1, -:ny ] (1,0,0) y-faces
199  // and requires Hvom on [ 0:nx-1,-2:ny+1] (0,0,0) y-faces
200 
201  // Grow ybx by one in low y-direction
202  ParallelFor(growLo(ybx,1,1), [=] AMREX_GPU_DEVICE (int i, int j, int k)
203  {
204  Real cff1=vold(i,j,k,nrhs)+vold(i,j+1,k,nrhs);
205 
206  // Upwinding
207  Real cff = (cff1 > 0.0) ? vold(i,j-1,k,nrhs)-2.0*vold(i,j,k,nrhs)+ vold(i,j+1,k,nrhs) :
208  vold(i,j,k,nrhs)-2.0*vold(i,j+1,k,nrhs)+ vold(i,j+2,k,nrhs);
209 
210  Real Hvee_j = Hvom(i,j-1,k)-2.0*Hvom(i,j ,k)+Hvom(i,j+1,k);
211  Real Hvee_jp1 = Hvom(i,j ,k)-2.0*Hvom(i,j+1,k)+Hvom(i,j+2,k);
212 
213  VFe(i,j,k) = 0.25 * (cff1+Gadv*cff) * ( Hvom(i,j ,k)+ Hvom(i,j+1,k) + 0.5 * Gadv * (Hvee_j + Hvee_jp1) );
214  });
215 
216  // Grow ybx by one in high x-direction
217  ParallelFor(growHi(ybx,0,1), [=] AMREX_GPU_DEVICE (int i, int j, int k)
218  {
219  Real cff1 = vold(i,j,k,nrhs) + vold(i-1,j ,k,nrhs);
220  Real cff2 = Huon(i,j,k) + Huon(i ,j-1,k);
221 
222  // Upwinding
223  Real cff = (cff2 > 0.0) ? vold(i-2,j,k,nrhs)-2.0*vold(i-1,j,k,nrhs)+vold(i ,j,k,nrhs) :
224  vold(i-1,j,k,nrhs)-2.0*vold(i ,j,k,nrhs)+vold(i+1,j,k,nrhs);
225 
226  Real Huee_j = Huon(i,j-1,k)-2.0*Huon(i,j ,k)+Huon(i,j+1,k);
227  Real Huee_jm1 = Huon(i,j-2,k)-2.0*Huon(i,j-1,k)+Huon(i,j ,k);
228 
229  VFx(i,j,k) = 0.25*(cff1+Gadv*cff)* (cff2+Gadv*0.5*(Huee_j + Huee_jm1));
230  });
231 
232  ParallelFor(ybx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
233  {
234  rv(i,j,k,nrhs) -= ( (VFx(i+1,j,k)-VFx(i,j,k)) + (VFe(i,j,k)-VFe(i,j-1,k)) );
235  });
236 
237  ParallelFor(ybx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
238  {
239  Real cff1=9.0/16.0;
240  Real cff2=1.0/16.0;
241  if (k>=1 && k<=N-2)
242  {
243  FC(i,j,k)=( cff1*(vold(i,j,k ,nrhs)+ vold(i,j,k+1,nrhs))
244  -cff2*(vold(i,j,k-1,nrhs)+ vold(i,j,k+2,nrhs)) )*
245  ( cff1*(W(i,j ,k)+ W(i,j-1,k))
246  -cff2*(W(i,j+1,k)+ W(i,j-2,k)) );
247  }
248  else // this needs to be split up so that the following can be concurrent
249  {
250  FC(i,j,N)=0.0;
251  FC(i,j,N-1)=( cff1*(vold(i,j,N-1,nrhs)+ vold(i,j,N ,nrhs))
252  -cff2*(vold(i,j,N-2,nrhs)+ vold(i,j,N ,nrhs)) )*
253  ( cff1*(W(i,j ,N-1)+ W(i,j-1,N-1))
254  -cff2*(W(i,j+1,N-1)+ W(i,j-2,N-1)) );
255  FC(i,j,0)=( cff1*(vold(i,j,0,nrhs)+ vold(i,j,1,nrhs))
256  -cff2*(vold(i,j,0,nrhs)+ vold(i,j,2,nrhs)) )*
257  ( cff1*(W(i,j ,0)+ W(i,j-1,0))
258  -cff2*(W(i,j+1,0)+ W(i,j-2,0)) );
259  // FC(i,0,-1)=0.0;
260  }
261  }); Gpu::synchronize();
262 
263  ParallelFor(ybx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
264  {
265  Real cff = (k >= 1) ? FC(i,j,k)-FC(i,j,k-1) : FC(i,j,k);
266 
267  rv(i,j,k,nrhs) -= cff;
268  });
269 
270  Gpu::synchronize();
271 
272  AMREX_ASSERT(ybx.smallEnd(2) == 0 && ybx.bigEnd(2) == N);
273  ParallelFor(makeSlab(ybx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
274  {
275  for (int k = 0; k <= N; ++k)
276  {
277  rvfrc(i,j,0) += rv(i,j,k,nrhs);
278 
279  Real om_v = 2.0_rt / (pm(i,j-1,0)+pm(i,j,0));
280  Real on_v = 2.0_rt / (pn(i,j-1,0)+pn(i,j,0));
281  Real cff = om_v * on_v;
282 
283  Real cff1 = (k == N) ? svstr(i,j,0)*cff : 0.0_rt;
284  Real cff2 = (k == 0) ? -bvstr(i,j,0)*cff : 0.0_rt;
285 
286  rvfrc(i,j,0) += cff1+cff2;
287  }
288  });
289 }

◆ set_2darrays()

void REMORA::set_2darrays ( int  lev)
83 {
84  std::unique_ptr<MultiFab>& mf_x_r = vec_x_r[lev];
85  std::unique_ptr<MultiFab>& mf_y_r = vec_y_r[lev];
86  auto N = Geom(lev).Domain().size()[2]-1; // Number of vertical "levs" aka, NZ
87 
88  for ( MFIter mfi(*(mf_x_r), TilingIfNotGPU()); mfi.isValid(); ++mfi )
89  {
90 
91  Array4<Real> const& x_r = (mf_x_r)->array(mfi);
92  Array4<Real> const& y_r = (mf_y_r)->array(mfi);
93  const Box& bx = mfi.growntilebox();
94  const auto & geomdata = Geom(lev).data();
95  Gpu::synchronize();
96  amrex::ParallelFor(amrex::makeSlab(bx,2,0),
97  [=] AMREX_GPU_DEVICE (int i, int j, int )
98  {
99  const auto prob_lo = geomdata.ProbLo();
100  const auto dx = geomdata.CellSize();
101 
102  x_r(i,j,0) = prob_lo[0] + (i + 0.5) * dx[0];
103  y_r(i,j,0) = prob_lo[1] + (j + 0.5) * dx[1];
104  // const Real z = prob_lo[2] + (k + 0.5) * dx[2];
105 
106  });
107  }
108 
109  MultiFab* U_old = xvel_new[lev];
110  MultiFab* V_old = yvel_new[lev];
111  std::unique_ptr<MultiFab>& mf_ubar = vec_ubar[lev];
112  std::unique_ptr<MultiFab>& mf_vbar = vec_vbar[lev];
113  std::unique_ptr<MultiFab>& mf_Hz = vec_Hz[lev];
114  int nstp = 0;
115  int kstp = 0;
116  int knew = 0;
117 
118  for ( MFIter mfi(*cons_new[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi )
119  {
120  Array4<Real> const& ubar = (mf_ubar)->array(mfi);
121  Array4<Real> const& vbar = (mf_vbar)->array(mfi);
122 
123  Array4<const Real> const& Hz = mf_Hz->const_array(mfi);
124  Array4<const Real> const& u = U_old->const_array(mfi);
125  Array4<const Real> const& v = V_old->const_array(mfi);
126 
127  Box ubx2 = mfi.nodaltilebox(0); ubx2.grow(IntVect(NGROW ,NGROW ,0)); // x-face-centered, grown by 2
128  Box vbx2 = mfi.nodaltilebox(1); vbx2.grow(IntVect(NGROW ,NGROW ,0)); // y-face-centered, grown by 2
129 
130  amrex::ParallelFor(makeSlab(ubx2,2,0),
131  [=] AMREX_GPU_DEVICE (int i, int j, int )
132  {
133  Real CF = 0.;
134  Real sum_of_hz = 0.;
135 
136  for (int k=0; k<=N; k++) {
137  Real avg_hz = 0.5*(Hz(i,j,k)+Hz(i-1,j,k));
138  sum_of_hz += avg_hz;
139  CF += avg_hz*u(i,j,k,nstp);
140  }
141  ubar(i,j,0,kstp) = CF / sum_of_hz;
142  ubar(i,j,0,knew) = CF / sum_of_hz;
143  });
144 
145  amrex::ParallelFor(makeSlab(vbx2,2,0),
146  [=] AMREX_GPU_DEVICE (int i, int j, int )
147  {
148  Real CF = 0.;
149  Real sum_of_hz = 0.;
150 
151  for(int k=0; k<=N; k++) {
152  Real avg_hz = 0.5*(Hz(i,j,k)+Hz(i,j-1,k));
153  sum_of_hz += avg_hz;
154  CF += avg_hz*v(i,j,k,nstp);
155  }
156  vbar(i,j,0,kstp) = CF / sum_of_hz;
157  vbar(i,j,0,knew) = CF / sum_of_hz;
158  });
159  }
160 
161  // DEBUGGING NOTE -- DoublyPeriodic fails if these are commented out
162  const Real time = 0.0;
163  FillPatch(lev,time, *vec_ubar[lev], GetVecOfPtrs(vec_ubar), BdyVars::ubar);
164  FillPatch(lev,time, *vec_vbar[lev], GetVecOfPtrs(vec_vbar), BdyVars::vbar);
165 }

◆ set_bathymetry()

void REMORA::set_bathymetry ( int  lev)
373 {
376 
377 #ifdef REMORA_USE_NETCDF
378  } else if (solverChoice.ic_bc_type == IC_BC_Type::Real) {
379  amrex::Print() << "Calling init_bathymetry_from_netcdf " << std::endl;
380  init_bathymetry_from_netcdf(lev);
381  amrex::Print() << "Bathymetry loaded from netcdf file \n " << std::endl;
382 #endif
383  } else {
384  Abort("Don't know this ic_bc_type!");
385  }
386 
387  // HACK -- SHOULD WE ALWAYS DO THIS??
388  vec_Zt_avg1[lev]->setVal(0.0);
389 
390  Real time = 0.0;
391  FillPatch(lev, time, *vec_Zt_avg1[lev], GetVecOfPtrs(vec_Zt_avg1));
392  FillPatch(lev, time, *vec_hOfTheConfusingName[lev], GetVecOfPtrs(vec_hOfTheConfusingName));
393 }
void init_custom_bathymetry(const amrex::Geometry &geom, amrex::MultiFab &mf_h, SolverChoice const &m_solverChoice)
Here is the call graph for this function:

◆ set_coriolis()

void REMORA::set_coriolis ( int  lev)
396  {
399  init_custom_coriolis(geom[lev], *vec_fcor[lev], solverChoice);
402 #ifdef REMORA_USE_NETCDF
403  } else if (solverChoice.coriolis_type == Cor_Type::Real) {
404  amrex::Print() << "Calling init_coriolis_from_netcdf " << std::endl;
405  init_coriolis_from_netcdf(lev);
406  amrex::Print() << "Coriolis loaded from netcdf file \n" << std::endl;
407 #endif
408  } else {
409  Abort("Don't know this coriolis_type!");
410  }
411 
412  Real time = 0.0;
413  FillPatch(lev, time, *vec_fcor[lev], GetVecOfPtrs(vec_fcor));
414  }
415 }
void init_beta_plane_coriolis(int lev)
Definition: REMORA_init.cpp:54
void init_custom_coriolis(const amrex::Geometry &geom, amrex::MultiFab &mf_fcor, SolverChoice const &m_solverChoice)
Cor_Type coriolis_type
Definition: DataStruct.H:211
Here is the call graph for this function:

◆ set_drag()

void REMORA::set_drag ( int  lev)

◆ set_hmixcoef()

void REMORA::set_hmixcoef ( int  lev)
428 {
429  init_custom_hmix(geom[lev], *vec_visc2_p[lev], *vec_visc2_r[lev], *vec_diff2[lev], solverChoice);
430 
431  Real time = 0.0;
432  FillPatch(lev, time, *vec_visc2_p[lev], GetVecOfPtrs(vec_visc2_p));
433  FillPatch(lev, time, *vec_visc2_r[lev], GetVecOfPtrs(vec_visc2_r));
434  FillPatch(lev, time, *vec_diff2[lev] , GetVecOfPtrs(vec_diff2));
435 }
void init_custom_hmix(const amrex::Geometry &geom, amrex::MultiFab &mf_visc2_p, amrex::MultiFab &mf_visc2_r, amrex::MultiFab &mf_diff2, SolverChoice const &m_solverChoice)
Here is the call graph for this function:

◆ set_smflux()

void REMORA::set_smflux ( int  lev,
amrex::Real  time 
)
439 {
440  init_custom_smflux(geom[lev], time, *vec_sustr[lev], *vec_svstr[lev], solverChoice);
441 
442  // FillPatch(lev, time, *vec_sustr[lev], GetVecOfPtrs(vec_sustr));
443  // FillPatch(lev, time, *vec_svstr[lev], GetVecOfPtrs(vec_svstr));
444 }
void init_custom_smflux(const amrex::Geometry &geom, amrex::Real time, amrex::MultiFab &mf_sustr, amrex::MultiFab &mf_svstr, SolverChoice const &m_solverChoice)
Here is the call graph for this function:

◆ set_vmix()

void REMORA::set_vmix ( int  lev)
418  {
419  init_custom_vmix(geom[lev], *vec_Akv[lev], *vec_Akt[lev], *vec_z_w[lev], solverChoice);
420 
421  Real time = 0.0;
422  FillPatch(lev, time, *vec_Akv[lev], GetVecOfPtrs(vec_Akv));
423  FillPatch(lev, time, *vec_Akt[lev], GetVecOfPtrs(vec_Akt));
424 }
void init_custom_vmix(const amrex::Geometry &geom, amrex::MultiFab &mf_Akv, amrex::MultiFab &mf_Akt, amrex::MultiFab &mf_z_w, SolverChoice const &m_solverChoice)
Here is the call graph for this function:

◆ set_weights()

void REMORA::set_weights ( int  lev)
10  {
11 
12  Real gamma, scale;
13  Real wsum, shift, cff;
14 
15  //HACK should possibly store fixed_ndtfast elsewhere
16  int ndtfast=fixed_ndtfast_ratio>0 ? fixed_ndtfast_ratio : static_cast<int>(fixed_fast_dt / fixed_dt);
17 
18  //From mod_scalars
19  Real Falpha = 2.0_rt;
20  Real Fbeta = 4.0_rt;
21  Real Fgamma = 0.284_rt;
22 
23  vec_weight1.resize(2*ndtfast+1);
24  vec_weight2.resize(2*ndtfast+1);
25 
26  auto weight1 = vec_weight1.dataPtr();
27  auto weight2 = vec_weight2.dataPtr();
28 
29 //
30 //=======================================================================
31 // Compute time-averaging filter for barotropic fields.
32 //=======================================================================
33 //
34 // Initialize both sets of weights to zero.
35 //
36  nfast=0;
37  for(int i=1;i<=2*ndtfast;i++) {
38  weight1[i-1]=0.0_rt;
39  weight2[i-1]=0.0_rt;
40  }
41 //
42 //-----------------------------------------------------------------------
43 // Power-law shape filters.
44 //-----------------------------------------------------------------------
45 //
46 // The power-law shape filters are given by:
47 //
48 // F(xi)=xi^Falpha*(1-xi^Fbeta)-Fgamma*xi
49 //
50 // where xi=scale*i/ndtfast; and scale, Falpha, Fbeta, Fgamma, and
51 // normalization are chosen to yield the correct zeroth-order
52 // (normalization), first-order (consistency), and second-order moments,
53 // resulting in overall second-order temporal accuracy for time-averaged
54 // barotropic motions resolved by baroclinic time step.
55 //
56  scale=(Falpha+1.0_rt)*(Falpha+Fbeta+1.0_rt) /
57  ((Falpha+2.0_rt)*(Falpha+Fbeta+2.0_rt)*Real(ndtfast));
58  //
59  // Find center of gravity of the primary weighting shape function and
60  // iteratively adjust "scale" to place the centroid exactly at
61  // "ndtfast".
62  //
63  gamma = Fgamma*max(0.0_rt, 1.0_rt-10.0_rt/Real(ndtfast));
64 
65  for (int iter=1;iter<=16;iter++) {
66  nfast=0;
67  for(int i=1;i<=2*ndtfast;i++) {
68  cff=scale*Real(i);
69 
70  weight1[i-1]=pow(cff,Falpha)-pow(cff,(Falpha+Fbeta))-gamma*cff;
71 
72  if (weight1[i-1] > 0.0_rt) {
73  nfast=i;
74  }
75 
76  if ( (nfast>0) && (weight1[i-1] < 0.0_rt) ) {
77  weight1[i-1] = 0.0_rt;
78  }
79  }
80  wsum = 0.0_rt;
81  shift = 0.0_rt;
82  for(int i=1;i<=nfast;i++) {
83  wsum=wsum+weight1[i-1];
84  shift=shift+weight1[i-1]*Real(i);
85  }
86  scale *= shift/(wsum*Real(ndtfast));
87  }
88 //
89 //-----------------------------------------------------------------------
90 // Post-processing of primary weights.
91 //-----------------------------------------------------------------------
92 //
93 // Although it is assumed that the initial settings of the primary
94 // weights has its center of gravity "reasonably close" to NDTFAST,
95 // it may be not so according to the discrete rules of integration.
96 // The following procedure is designed to put the center of gravity
97 // exactly to NDTFAST by computing mismatch (NDTFAST-shift) and
98 // applying basically an upstream advection of weights to eliminate
99 // the mismatch iteratively. Once this procedure is complete primary
100 // weights are normalized.
101 //
102 // Find center of gravity of the primary weights and subsequently
103 // calculate the mismatch to be compensated.
104 //
105  for (int iter=1;iter<=ndtfast;iter++) {
106  wsum = 0.0_rt;
107  shift = 0.0_rt;
108  for(int i=1;i<=nfast;i++) {
109  wsum=wsum+weight1[i-1];
110  shift=shift+Real(i)*weight1[i-1];
111  }
112  shift=shift/wsum;
113  cff=Real(ndtfast)-shift;
114  //
115  // Apply advection step using either whole, or fractional shifts.
116  // Notice that none of the four loops here is reversible.
117  //
118  if (cff > 1.0_rt) {
119  nfast=nfast+1;
120  for (int i=nfast;i>=2;i--) {
121  weight1[i-1]=weight1[i-1-1];
122  }
123  weight1[1-1] = 0.0_rt;
124  } else if (cff> 0.0_rt) {
125  wsum=1.0_rt-cff;
126  for (int i=nfast;i>=2;i--) {
127  weight1[i-1]=wsum*weight1[i-1]+cff*weight1[i-1-1];
128  }
129  weight1[1-1]=wsum*weight1[1-1];
130  } else if (cff < -1.0_rt) {
131  nfast=nfast-1;
132  for (int i=1;i<=nfast;i++) {
133  weight1[i-1]=weight1[i+1-1];
134  }
135  weight1[nfast+1-1] = 0.0_rt;
136  } else if (cff < 0.0_rt) {
137  wsum=1.0_rt+cff;
138  for (int i=1;i<=nfast-1;i++) {
139  weight1[i-1]=wsum*weight1[i-1]-cff*weight1[i+1-1];
140  }
141  weight1[nfast-1]=wsum*weight1[nfast-1];
142  }
143  }
144 
145  // Set SECONDARY weights assuming that backward Euler time step is used
146  // for free surface. Notice that array weight2[i] is assumed to
147  // have all-zero status at entry in this segment of code.
148  for(int j=1;j<=nfast;j++) {
149  cff=weight1[j-1];
150  for(int i=1;i<=j;i++) {
151  weight2[i-1]=weight2[i-1]+cff;
152  }
153  }
154 
155  //
156  // Normalize both set of weights.
157  //
158  wsum = 0.0_rt;
159  cff = 0.0_rt;
160  for(int i=1;i<=nfast;i++) {
161  wsum=wsum+weight1[i-1];
162  cff=cff+weight2[i-1];
163  }
164 
165  wsum = 1.0_rt / wsum;
166  cff = 1.0_rt / cff;
167 
168  for(int i=1;i<=nfast;i++) {
169  weight1[i-1]=wsum*weight1[i-1];
170  weight2[i-1]=cff*weight2[i-1];
171  }
172 //
173 // Report weights.
174 //
175 #if 0
176  Real cff1, cff2;
177  if (ParallelDescriptor::IOProcessor()) {
178  Print().SetPrecision(18)<<ParallelDescriptor::NProcs()<<" "<<ndtfast<<" "<<nfast<<" "<<wsum<<std::endl;
179  cff=0.0_rt;
180  cff1=0.0_rt;
181  cff2=0.0_rt;
182  wsum=0.0_rt;
183  shift=0.0_rt;
184  for(int i=1;i<=nfast;i++) {
185  cff=cff+weight1[i-1];
186  cff1=cff1+weight1[i-1]*Real(i);
187  cff2=cff2+weight1[i-1]*Real(i*i);
188  wsum=wsum+weight2[i-1];
189  shift=shift+weight2[i-1]*(Real(i)-0.5_rt);
190  Print().SetPrecision(18)<<"i="<<i<<" "<<weight1[i-1]<<" "<<weight2[i-1]<<" "<<cff<<" "<<wsum<<std::endl;
191  }
192  cff1=cff1/Real(ndtfast);
193  cff2=cff2/(Real(ndtfast)*Real(ndtfast));
194  shift=shift/Real(ndtfast);
195  Print().SetPrecision(18)<<ndtfast <<" "<< nfast<<" "<<Real(nfast)/Real(ndtfast)<<std::endl;
196  Print().SetPrecision(18)<<cff1<<" "<<cff2<<" "<<shift<<" "<<cff<<" "<<wsum<<" "<<Fgamma<<" "<<gamma<<std::endl;
197  if (cff2<1.0001_rt) Print()<<"\n\n\n"<<std::endl;
198  }
199 #endif
200 }

◆ setPlotVariables()

void REMORA::setPlotVariables ( const std::string &  pp_plot_var_names,
amrex::Vector< std::string > &  plot_var_names 
)
private

set which variables and derived quantities go into plotfiles

10 {
11  ParmParse pp(pp_prefix);
12 
13  if (pp.contains(pp_plot_var_names.c_str()))
14  {
15  std::string nm;
16 
17  int nPltVars = pp.countval(pp_plot_var_names.c_str());
18 
19  for (int i = 0; i < nPltVars; i++)
20  {
21  pp.get(pp_plot_var_names.c_str(), nm, i);
22 
23  // Add the named variable to our list of plot variables
24  // if it is not already in the list
25  if (!containerHasElement(plot_var_names, nm)) {
26  plot_var_names.push_back(nm);
27  }
28  }
29  } else {
30  //
31  // The default is to add none of the variables to the list
32  //
33  plot_var_names.clear();
34  }
35 
36  // Get state variables in the same order as we define them,
37  // since they may be in any order in the input list
38  Vector<std::string> tmp_plot_names;
39 
40  for (int i = 0; i < NCONS; ++i) {
41  if ( containerHasElement(plot_var_names, cons_names[i]) ) {
42  tmp_plot_names.push_back(cons_names[i]);
43  }
44  }
45  // Check for velocity since it's not in cons_names
46  // If we are asked for any velocity component, we will need them all
47  if (containerHasElement(plot_var_names, "x_velocity") ||
48  containerHasElement(plot_var_names, "y_velocity") ||
49  containerHasElement(plot_var_names, "z_velocity")) {
50  tmp_plot_names.push_back("x_velocity");
51  tmp_plot_names.push_back("y_velocity");
52  tmp_plot_names.push_back("z_velocity");
53  }
54 
55  // If we are asked for any location component, we will provide them all
56  if (containerHasElement(plot_var_names, "x_cc") ||
57  containerHasElement(plot_var_names, "y_cc") ||
58  containerHasElement(plot_var_names, "z_cc")) {
59  tmp_plot_names.push_back("x_cc");
60  tmp_plot_names.push_back("y_cc");
61  tmp_plot_names.push_back("z_cc");
62  }
63 
64  for (int i = 0; i < derived_names.size(); ++i) {
65  if ( containerHasElement(plot_var_names, derived_names[i]) ) {
66 #ifdef REMORA_USE_PARTICLES
67  if (particleData.use_tracer_particles || (derived_names[i] != "tracer_particle_count")) {
68 #endif
69  tmp_plot_names.push_back(derived_names[i]);
70 #ifdef REMORA_USE_PARTICLES
71  }
72 #endif
73  } // if
74  } // i
75 
76  // Check to see if we found all the requested variables
77  for (auto plot_name : plot_var_names) {
78  if (!containerHasElement(tmp_plot_names, plot_name)) {
79  Warning("\nWARNING: Requested to plot variable '" + plot_name + "' but it is not available");
80  }
81  }
82  plot_var_names = tmp_plot_names;
83 }
bool containerHasElement(const V &iterable, const T &query)
Definition: REMORA.H:63
const amrex::Vector< std::string > cons_names
Definition: REMORA.H:811
const amrex::Vector< std::string > derived_names
Definition: REMORA.H:817
Here is the call graph for this function:

◆ setRecordDataInfo()

void REMORA::setRecordDataInfo ( int  i,
const std::string &  filename 
)
inlineprivate
955  {
956  if (amrex::ParallelDescriptor::IOProcessor())
957  {
958  datalog[i] = std::make_unique<std::fstream>();
959  datalog[i]->open(filename.c_str(),std::ios::out|std::ios::app);
960  if (!datalog[i]->good()) {
961  amrex::FileOpenFailed(filename);
962  }
963  }
964  amrex::ParallelDescriptor::Barrier("REMORA::setRecordDataInfo");
965  }

◆ setup_step()

void REMORA::setup_step ( int  lev,
amrex::Real  time,
amrex::Real  dt_lev 
)

Set everything up for a step on a level

8 {
9  BL_PROFILE("REMORA::setup_step()");
10 
11  MultiFab& S_old = *cons_old[lev];
12  MultiFab& S_new = *cons_new[lev];
13 
14  MultiFab& U_old = *xvel_old[lev];
15  MultiFab& V_old = *yvel_old[lev];
16  MultiFab& W_old = *zvel_old[lev];
17 
18  MultiFab& U_new = *xvel_new[lev];
19  MultiFab& V_new = *yvel_new[lev];
20  MultiFab& W_new = *zvel_new[lev];
21 
22  int nvars = S_old.nComp();
23 
24  // Fill ghost cells/faces at old time
25  FillPatch(lev, time, *cons_old[lev], cons_old, BdyVars::t);
26  FillPatch(lev, time, *xvel_old[lev], xvel_old, BdyVars::u);
27  FillPatch(lev, time, *yvel_old[lev], yvel_old, BdyVars::v);
28  FillPatch(lev, time, *zvel_old[lev], zvel_old, BdyVars::null);
29 
30  ////////// //pre_step3d corrections to boundaries
31 
32  const BoxArray& ba = S_old.boxArray();
33  const DistributionMapping& dm = S_old.DistributionMap();
34 
35  const int nrhs = 0;
36  const int nstp = 0;
37 
38  // Place-holder for source array -- for now just set to 0
39  MultiFab source(ba,dm,nvars,1);
40  source.setVal(0.0);
41 
42  //-----------------------------------------------------------------------
43  // Time step momentum equation
44  //-----------------------------------------------------------------------
45 
46  //Only used locally, probably should be rearranged into FArrayBox declaration
47  MultiFab mf_AK(ba,dm,1,IntVect(NGROW,NGROW,0)); //2d missing j coordinate
48  MultiFab mf_DC(ba,dm,1,IntVect(NGROW,NGROW,NGROW-1)); //2d missing j coordinate
49  MultiFab mf_Hzk(ba,dm,1,IntVect(NGROW,NGROW,NGROW-1)); //2d missing j coordinate
50 
51  MultiFab* mf_z_r = vec_z_r[lev].get();
52  MultiFab* mf_z_w = vec_z_w[lev].get();
53  MultiFab* mf_h = vec_hOfTheConfusingName[lev].get();
54  MultiFab* mf_pm = vec_pm[lev].get();
55  MultiFab* mf_pn = vec_pn[lev].get();
56  MultiFab* mf_fcor = vec_fcor[lev].get();
57 
58  //Consider passing these into the advance function or renaming relevant things
59 
60  MultiFab mf_rho(ba,dm,1,IntVect(NGROW,NGROW,0));
61  std::unique_ptr<MultiFab>& mf_rhoS = vec_rhoS[lev];
62  std::unique_ptr<MultiFab>& mf_rhoA = vec_rhoA[lev];
63  std::unique_ptr<MultiFab>& mf_ru = vec_ru[lev];
64  std::unique_ptr<MultiFab>& mf_rv = vec_rv[lev];
65  std::unique_ptr<MultiFab>& mf_rufrc = vec_rufrc[lev];
66  std::unique_ptr<MultiFab>& mf_rvfrc = vec_rvfrc[lev];
67  std::unique_ptr<MultiFab>& mf_sustr = vec_sustr[lev];
68  std::unique_ptr<MultiFab>& mf_svstr = vec_svstr[lev];
69  std::unique_ptr<MultiFab>& mf_rdrag = vec_rdrag[lev];
70  std::unique_ptr<MultiFab>& mf_bustr = vec_bustr[lev];
71  std::unique_ptr<MultiFab>& mf_bvstr = vec_bvstr[lev];
72 
73  MultiFab mf_rw(ba,dm,1,IntVect(NGROW,NGROW,0));
74 
75  std::unique_ptr<MultiFab>& mf_visc2_p = vec_visc2_p[lev];
76  std::unique_ptr<MultiFab>& mf_visc2_r = vec_visc2_r[lev];
77 
78  // We need to set these because otherwise in the first call to remora_advance we may
79  // read uninitialized data on ghost values in setting the bc's on the velocities
80  mf_rho.setVal(0.e34,IntVect(AMREX_D_DECL(NGROW-1,NGROW-1,0)));
81  mf_rhoS->setVal(0.e34,IntVect(AMREX_D_DECL(NGROW-1,NGROW-1,0)));
82  mf_rhoA->setVal(0.e34,IntVect(AMREX_D_DECL(NGROW-1,NGROW-1,0)));
83 
84  mf_DC.setVal(0);
85 
86  FillPatch(lev, time, *cons_old[lev], cons_old, BdyVars::t);
87  FillPatch(lev, time, *xvel_old[lev], xvel_old, BdyVars::u);
88  FillPatch(lev, time, *yvel_old[lev], yvel_old, BdyVars::v);
89 
90  FillPatch(lev, time, *cons_new[lev], cons_new, BdyVars::t);
91  FillPatch(lev, time, *xvel_new[lev], xvel_new, BdyVars::u);
92  FillPatch(lev, time, *yvel_new[lev], yvel_new, BdyVars::v);
93 
94  mf_rw.setVal(0.0);
95  mf_rufrc->setVal(0);
96  mf_rvfrc->setVal(0);
97 
98  int iic = istep[lev];
99  int ntfirst = 0;
100  if(iic==ntfirst) {
101  MultiFab::Copy(S_new,S_old,0,0,S_new.nComp(),S_new.nGrowVect());
102  MultiFab::Copy(U_new,U_old,0,0,U_new.nComp(),U_new.nGrowVect());
103  MultiFab::Copy(V_new,V_old,0,0,V_new.nComp(),V_new.nGrowVect());
104  MultiFab::Copy(W_new,W_old,0,0,W_new.nComp(),W_new.nGrowVect());
105  }
106  set_smflux(lev,t_old[lev]);
107 
108  auto N = Geom(lev).Domain().size()[2]-1; // Number of vertical "levs" aka, NZ
109 
110  for ( MFIter mfi(S_new, TilingIfNotGPU()); mfi.isValid(); ++mfi )
111  {
112  Array4<Real const> const& h = vec_hOfTheConfusingName[lev]->const_array(mfi);
113  Array4<Real const> const& Hz = vec_Hz[lev]->const_array(mfi);
114  Array4<Real > const& Huon = vec_Huon[lev]->array(mfi);
115  Array4<Real > const& Hvom = vec_Hvom[lev]->array(mfi);
116 
117  Array4<Real const> const& z_w = mf_z_w->const_array(mfi);
118  Array4<Real const> const& uold = U_old.const_array(mfi);
119  Array4<Real const> const& vold = V_old.const_array(mfi);
120  Array4<Real > const& rho = mf_rho.array(mfi);
121  Array4<Real > const& rhoA = mf_rhoA->array(mfi);
122  Array4<Real > const& rhoS = mf_rhoS->array(mfi);
123  Array4<Real const> const& rdrag = mf_rdrag->const_array(mfi);
124  Array4<Real > const& bustr = mf_bustr->array(mfi);
125  Array4<Real > const& bvstr = mf_bvstr->array(mfi);
126 
127  Array4<Real const> const& pm = mf_pm->const_array(mfi);
128  Array4<Real const> const& pn = mf_pn->const_array(mfi);
129 
130  Box bx = mfi.tilebox();
131  Box gbx1 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
132  Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
133 
134  Box bxD = bx;
135  bxD.makeSlab(2,0);
136  Box gbx1D = gbx1;
137  gbx1D.makeSlab(2,0);
138  Box gbx2D = gbx2;
139  gbx2D.makeSlab(2,0);
140 
141  FArrayBox fab_FC(gbx2,1,amrex::The_Async_Arena()); //3D
142  FArrayBox fab_FX(gbx2,1,amrex::The_Async_Arena()); //3D
143  FArrayBox fab_FE(gbx2,1,amrex::The_Async_Arena()); //3D
144  FArrayBox fab_BC(gbx2,1,amrex::The_Async_Arena());
145  FArrayBox fab_CF(gbx2,1,amrex::The_Async_Arena());
146 
147  // Set bottom stress as defined in set_vbx.F
148  ParallelFor(gbx1D, [=] AMREX_GPU_DEVICE (int i, int j, int )
149  {
150  bustr(i,j,0) = 0.5 * (rdrag(i-1,j,0)+rdrag(i,j,0))*(uold(i,j,0));
151  bvstr(i,j,0) = 0.5 * (rdrag(i,j-1,0)+rdrag(i,j,0))*(vold(i,j,0));
152  });
153 
154  //
155  //-----------------------------------------------------------------------
156  // Compute horizontal mass fluxes, Hz*u/n and Hz*v/m (set_massflux_3d)
157  //-----------------------------------------------------------------------
158  //
159  ParallelFor(Box(Huon), [=] AMREX_GPU_DEVICE (int i, int j, int k)
160  {
161  Real on_u = 2.0 / (pn(i-1,j,0)+pn(i,j,0));
162  Huon(i,j,k)=0.5*(Hz(i,j,k)+Hz(i-1,j,k))*uold(i,j,k)* on_u;
163  });
164 
165  ParallelFor(Box(Hvom), [=] AMREX_GPU_DEVICE (int i, int j, int k)
166  {
167  Real om_v= 2.0 / (pm(i,j-1,0)+pm(i,j,0));
168  Hvom(i,j,k)=0.5*(Hz(i,j,k)+Hz(i,j-1,k))*vold(i,j,k)* om_v;
169  });
170 
171  Array4<Real const> const& state_old = S_old.const_array(mfi);
172  rho_eos(gbx2,state_old,rho,rhoA,rhoS,Hz,z_w,h,N);
173  }
174 
175  MultiFab mf_W(ba,dm,1,IntVect(NGROW+1,NGROW+1,0));
176  mf_W.setVal(0.0);
177 
179  const int nnew = 0;
180  prestep(lev, U_old, V_old, U_new, V_new,
181  mf_ru.get(), mf_rv.get(),
182  S_old, S_new, mf_W,
183  mf_DC, mf_z_r, mf_z_w, mf_h, mf_pm, mf_pn,
184  mf_sustr.get(), mf_svstr.get(), mf_bustr.get(), mf_bvstr.get(),
185  iic, ntfirst, nnew, nstp, nrhs, N, dt_lev);
186  }
187 
188  // We use FillBoundary not FillPatch here since mf_W is single-level scratch space
189  mf_W.FillBoundary(geom[lev].periodicity());
190 
191  for ( MFIter mfi(S_old, TilingIfNotGPU()); mfi.isValid(); ++mfi )
192  {
193  Array4<Real const> const& Hz = vec_Hz[lev]->const_array(mfi);
194  Array4<Real> const& Huon = vec_Huon[lev]->array(mfi);
195  Array4<Real> const& Hvom = vec_Hvom[lev]->array(mfi);
196  Array4<Real> const& z_r = (mf_z_r)->array(mfi);
197  Array4<Real> const& z_w = (mf_z_w)->array(mfi);
198  Array4<Real const> const& uold = U_old.const_array(mfi);
199  Array4<Real const> const& vold = V_old.const_array(mfi);
200  Array4<Real> const& u = U_new.array(mfi);
201  Array4<Real> const& v = V_new.array(mfi);
202  Array4<Real> const& rho = (mf_rho).array(mfi);
203  Array4<Real> const& ru = (mf_ru)->array(mfi);
204  Array4<Real> const& rv = (mf_rv)->array(mfi);
205  Array4<Real> const& rufrc = (mf_rufrc)->array(mfi);
206  Array4<Real> const& rvfrc = (mf_rvfrc)->array(mfi);
207  Array4<Real> const& W = (mf_W).array(mfi);
208  Array4<Real> const& sustr = (mf_sustr)->array(mfi);
209  Array4<Real> const& svstr = (mf_svstr)->array(mfi);
210  Array4<Real> const& bustr = (mf_bustr)->array(mfi);
211  Array4<Real> const& bvstr = (mf_bvstr)->array(mfi);
212  Array4<Real> const& visc2_p = (mf_visc2_p)->array(mfi);
213  Array4<Real> const& visc2_r = (mf_visc2_r)->array(mfi);
214 
215  Array4<Real> const& zeta = (vec_zeta[lev])->array(mfi);
216  Array4<Real> const& Zt_avg1 = (vec_Zt_avg1[lev])->array(mfi);
217 
218  Array4<Real const> const& pm = mf_pm->const_array(mfi);
219  Array4<Real const> const& pn = mf_pn->const_array(mfi);
220  Array4<Real const> const& fcor = mf_fcor->const_array(mfi);
221 
222  Box bx = mfi.tilebox();
223 
224  Box tbxp1 = bx;
225  Box tbxp2 = bx;
226  Box xbx = mfi.nodaltilebox(0);
227  Box ybx = mfi.nodaltilebox(1);
228  Box gbx1 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
229  Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
230 
231  Box utbx = mfi.nodaltilebox(0);
232  Box vtbx = mfi.nodaltilebox(1);
233 
234  tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
235  tbxp2.grow(IntVect(NGROW,NGROW,0));
236 
237  Box bxD = bx;
238  bxD.makeSlab(2,0);
239  Box gbx1D = gbx1;
240  gbx1D.makeSlab(2,0);
241  Box gbx2D = gbx2;
242  gbx2D.makeSlab(2,0);
243 
244  Box tbxp1D = tbxp1;
245  tbxp1D.makeSlab(2,0);
246  Box tbxp2D = tbxp2;
247  tbxp2D.makeSlab(2,0);
248 
249  FArrayBox fab_FC(tbxp2,1,amrex::The_Async_Arena()); //3D
250  FArrayBox fab_FX(gbx2,1,amrex::The_Async_Arena()); //3D
251  FArrayBox fab_FE(gbx2,1,amrex::The_Async_Arena()); //3D
252  FArrayBox fab_BC(gbx2,1,amrex::The_Async_Arena());
253  FArrayBox fab_CF(gbx2,1,amrex::The_Async_Arena());
254 
255  FArrayBox fab_fomn(tbxp2D,1,amrex::The_Async_Arena());
256 
257  auto FC=fab_FC.array();
258 
259  auto fomn=fab_fomn.array();
260 
262  ParallelFor(tbxp2D, [=] AMREX_GPU_DEVICE (int i, int j, int )
263  {
264  fomn(i,j,0) = fcor(i,j,0)*(1.0/(pm(i,j,0)*pn(i,j,0)));
265  });
266  }
267 
268  ParallelFor(gbx2, [=] AMREX_GPU_DEVICE (int i, int j, int k)
269  {
270  FC(i,j,k)=0.0;
271  });
272 
273  prsgrd(tbxp1,gbx1,utbx,vtbx,ru,rv,pn,pm,rho,FC,Hz,z_r,z_w,nrhs,N);
274 
275  // Apply mixing to temperature and, if use_salt, salt
276  int ncomp = solverChoice.use_salt ? 2 : 1;
277  Array4<Real> const& s_arr = S_old.array(mfi);
278  Array4<Real> const& diff2_arr = vec_diff2[lev]->array(mfi);
279 
280  t3dmix(bx, s_arr, diff2_arr, Hz, pm, pn, dt_lev, ncomp);
281 
282  Array4<Real> const& diff2_arr_scalar = vec_diff2[lev]->array(mfi,Scalar_comp);
283  t3dmix(bx, S_old.array(mfi,Scalar_comp), diff2_arr_scalar, Hz, pm, pn, dt_lev, 1);
284 
286  //-----------------------------------------------------------------------
287  // coriolis
288  //-----------------------------------------------------------------------
289  //
290  // ru, rv updated
291  // In ROMS, coriolis is the first (un-ifdefed) thing to happen in rhs3d_tile, which gets called after t3dmix
292  coriolis(xbx, ybx, uold, vold, ru, rv, Hz, fomn, nrhs, nrhs);
293  }
294 
295  //
296  //-----------------------------------------------------------------------
297  //
298 
299  ////rufrc from 3d is set to ru, then the wind stress (and bottom stress) is added, then the mixing is added
300  //rufrc=ru+sustr*om_u*on_u
301 
302  rhs_uv_3d(xbx, ybx, uold, vold, ru, rv, rufrc, rvfrc,
303  sustr, svstr, bustr, bvstr, Huon, Hvom,
304  pm, pn, W, FC, nrhs, N);
305 
307  const int nnew = 0;
308  uv3dmix(xbx, ybx, u, v, uold, vold, rufrc, rvfrc, visc2_p, visc2_r, Hz, pm, pn, nrhs, nnew, dt_lev);
309  }
310 
311  // Set first two components of zeta to time-averaged values before barotropic update
312  ParallelFor(gbx2D, [=] AMREX_GPU_DEVICE (int i, int j, int)
313  {
314  zeta(i,j,0,0) = Zt_avg1(i,j,0);
315  zeta(i,j,0,1) = Zt_avg1(i,j,0);
316  });
317  } // MFIter
318 
319  // Update Akv with new depth. NOTE: this happens before set_zeta in ROMS
320  set_vmix(lev);
321 
322  FillPatch(lev, time, *cons_old[lev], cons_old, BdyVars::t);
323  FillPatch(lev, time, *cons_new[lev], cons_new, BdyVars::t);
324 
325  FillPatch(lev, time, *vec_sstore[lev], GetVecOfPtrs(vec_sstore), BdyVars::t);
326 
327  FillPatch(lev, time, *vec_Huon[lev], GetVecOfPtrs(vec_Huon));
328  FillPatch(lev, time, *vec_Hvom[lev], GetVecOfPtrs(vec_Hvom));
329 }
void set_smflux(int lev, amrex::Real time)
Definition: REMORA.cpp:438
void rhs_uv_3d(const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real > &rufrc, const amrex::Array4< amrex::Real > &rvfrc, const amrex::Array4< amrex::Real const > &sustr, const amrex::Array4< amrex::Real const > &svstr, const amrex::Array4< amrex::Real const > &bustr, const amrex::Array4< amrex::Real const > &bvstr, const amrex::Array4< amrex::Real const > &Huon, const amrex::Array4< amrex::Real const > &Hvom, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, const amrex::Array4< amrex::Real const > &W, const amrex::Array4< amrex::Real > &FC, int nrhs, int N)
Definition: REMORA_rhs_uv_3d.cpp:31
void t3dmix(const amrex::Box &bx, const amrex::Array4< amrex::Real > &state, const amrex::Array4< amrex::Real const > &diff2, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, const amrex::Real dt_lev, const int ncomp)
Definition: REMORA_t3dmix.cpp:6
void prestep(int lev, amrex::MultiFab &mf_uold, amrex::MultiFab &mf_vold, amrex::MultiFab &mf_u, amrex::MultiFab &mf_v, amrex::MultiFab *mf_ru, amrex::MultiFab *mf_rv, amrex::MultiFab &S_old, amrex::MultiFab &S_new, amrex::MultiFab &mf_W, amrex::MultiFab &mf_DC, const amrex::MultiFab *mf_z_r, const amrex::MultiFab *mf_z_w, const amrex::MultiFab *mf_h, const amrex::MultiFab *mf_pm, const amrex::MultiFab *mf_pn, const amrex::MultiFab *mf_sustr, const amrex::MultiFab *mf_svstr, const amrex::MultiFab *mf_bustr, const amrex::MultiFab *mf_bvstr, const int iic, const int nfirst, const int nnew, int nstp, int nrhs, int N, const amrex::Real dt_lev)
Definition: REMORA_prestep.cpp:34
void rho_eos(const amrex::Box &bx, const amrex::Array4< amrex::Real const > &state, const amrex::Array4< amrex::Real > &rho, const amrex::Array4< amrex::Real > &rhoA, const amrex::Array4< amrex::Real > &rhoS, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &z_w, const amrex::Array4< amrex::Real const > &h, const int N)
Definition: REMORA_rho_eos.cpp:20
void prsgrd(const amrex::Box &bx, const amrex::Box &gbx, const amrex::Box &utbx, const amrex::Box &vtbx, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real const > &pn, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &rho, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &z_r, const amrex::Array4< amrex::Real const > &z_w, const int nrhs, const int N)
Definition: REMORA_prsgrd.cpp:6
bool use_uv3dmix
Definition: DataStruct.H:198
bool use_prestep
Definition: DataStruct.H:197
bool use_salt
Definition: DataStruct.H:191

◆ stretch_transform()

void REMORA::stretch_transform ( int  lev)
13 {
14  std::unique_ptr<MultiFab>& mf_z_w = vec_z_w[lev];
15  std::unique_ptr<MultiFab>& mf_z_r = vec_z_r[lev];
16  std::unique_ptr<MultiFab>& mf_s_r = vec_s_r[lev];
17  std::unique_ptr<MultiFab>& mf_Hz = vec_Hz[lev];
18  std::unique_ptr<MultiFab>& mf_h = vec_hOfTheConfusingName[lev];
19  std::unique_ptr<MultiFab>& mf_Zt_avg1 = vec_Zt_avg1[lev];
20  std::unique_ptr<MultiFab>& mf_z_phys_nd = vec_z_phys_nd[lev];
21  auto N_loop = Geom(lev).Domain().size()[2]-1; // Number of vertical "levs" aka, NZ
22 
23  for ( MFIter mfi(*cons_new[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi )
24  {
25  Array4<Real> const& z_w = (mf_z_w)->array(mfi);
26  Array4<Real> const& z_r = (mf_z_r)->array(mfi);
27  Array4<Real> const& s_r = (mf_s_r)->array(mfi);
28  Array4<Real> const& Hz = (mf_Hz)->array(mfi);
29  Array4<Real> const& h = (mf_h)->array(mfi);
30  Array4<Real> const& Zt_avg1 = (mf_Zt_avg1)->array(mfi);
31  Box bx = mfi.tilebox();
32  Box gbx2 = bx;
33  gbx2.grow(IntVect(NGROW,NGROW,0));
34  Box gbx3 = bx;
35  gbx3.grow(IntVect(NGROW+1,NGROW+1,0));
36  Box gbx2D = gbx2;
37  gbx2D.makeSlab(2,0);
38  Box gbx3D = gbx3;
39  gbx3D.makeSlab(2,0);
40  Box wgbx3 = gbx3.surroundingNodes(2);
41 
42  const auto & geomdata = Geom(lev).data();
43 
44  int nz = geom[lev].Domain().length(2);
45 
46  auto N = nz; // Number of vertical "levels" aka, NZ
47  //forcing tcline to be the same as probhi for now, one in DataStruct.H other in inputs
48  Real hc=-min(geomdata.ProbHi(2),-solverChoice.tcline); // Do we need to enforce min here?
49  const auto local_theta_s = solverChoice.theta_s;
50  const auto local_theta_b = solverChoice.theta_b;
51 
52  amrex::ParallelFor(wgbx3, [=] AMREX_GPU_DEVICE (int i, int j, int k)
53  {
54  z_w(i,j,k) = h(i,j,0);
55  });
56 
57  // ROMS Transform 2
58  Gpu::streamSynchronize();
59 
60  amrex::ParallelFor(gbx3D, [=] AMREX_GPU_DEVICE (int i, int j, int )
61  {
62  for (int k=-1; k<=N_loop; k++) {
63  // const Real z = prob_lo[2] + (k + 0.5) * dx[2];
64  // const auto prob_lo = geomdata.ProbLo();
65  // const auto dx = geomdata.CellSize();
66  // This is the z for the bottom of the cell this k corresponds to
67  // if we weren't stretching and transforming
68  // const Real z = prob_lo[2] + (k) * dx[2];
69  // h(i,j,0) = -prob_lo[2]; // conceptually
70 
71  ////////////////////////////////////////////////////////////////////
72  //ROMS Stretching 4
73  // Move this block to it's own function for maintainability if needed
74  // Information about the problem dimension would need to be added
75  // This file would need a k dependent function to return the
76  // stretching scalars, or access to 4 vectors of length prob_length(2)
77  /////////////////////////////////////////////////////////////////////
78  Real ds = 1.0_rt / Real(N);
79 
80  Real cff_r, cff_w, cff1_r, cff1_w, cff2_r, cff2_w, Csur, Cbot;
81  Real sc_r,sc_w,Cs_r,Cs_w;
82 
83  if (k==N) // end of array // pretend we're storing 0?
84  {
85  sc_w=0.0; //sc_w / hc
86  Cs_w=0.0; //Cs_w
87  }
88  else if (k==0) // beginning of array
89  {
90  sc_w=-1.0; //sc_w / hc
91  Cs_w=-1.0; //Cs_w
92  }
93  else
94  {
95  sc_w=ds*(k-N);
96 
97  if (local_theta_s > 0.0_rt) {
98  Csur=(1.0_rt-std::cosh(local_theta_s*sc_w))/
99  (std::cosh(local_theta_s)-1.0_rt);
100  } else {
101  Csur=-sc_w*sc_w;
102  }
103 
104  if (local_theta_b > 0.0_rt) {
105  Cbot=(std::exp(local_theta_b*Csur)-1.0_rt)/
106  (1.0_rt-std::exp(-local_theta_b));
107  Cs_w=Cbot;
108  } else {
109  Cs_w=Csur;
110  }
111  } // k test
112 
113  cff_w=hc*sc_w;
114  cff1_w=Cs_w;
115 
116  //cff_r => sc_r *hc
117  //cff1_r => Cs_r
118  //Don't do anything special for first/last index
119  {
120  sc_r=ds*(k-N+0.5_rt);
121 
122  if (local_theta_s > 0.0_rt) {
123  Csur=(1.0_rt-std::cosh(local_theta_s*sc_r))/
124  (std::cosh(local_theta_s)-1.0_rt);
125  } else {
126  Csur=-sc_r*sc_r;
127  }
128 
129  if (local_theta_b > 0.0_rt) {
130  Cbot=(std::exp(local_theta_b*Csur)-1.0_rt)/
131  (1.0_rt-std::exp(-local_theta_b));
132  Cs_r=Cbot;
133  } else {
134  Cs_r=Csur;
135  }
136  }
137 
138  if (i==0&&j==0&&k<N&&k>=0) {
139  s_r(0,0,k) = sc_r;
140  }
141 
142  cff_r=hc*sc_r;
143  cff1_r=Cs_r;
144 
145  ////////////////////////////////////////////////////////////////////
146  Real hwater=h(i,j,0);
147  //
148  // if (k==0) //extra guess added (maybe not actually defined in ROMS)
149  // {
150  // Real hinv=1.0_rt/(hc+hwater);
151  // cff2_r=(cff_r+cff1_r*hwater)*hinv;
152  // // z_w(i,j,k-2) = hwater;
153  // // z_w(i,j,k-1)= -hwater;
154 
155  // z_r(i,j,k) = Zt_avg1(i,j,0)+(Zt_avg1(i,j,0)+hwater)*cff2_r;
156  // Hz(i,j,k)=z_w(i,j,k)+hwater;//-z_w(i,j,k-1);
157  // } else
158 
159  //Note, we are not supporting ICESHELF flag
160 
161  Real hinv=1.0_rt/(hc+hwater);
162  cff2_r=(cff_r+cff1_r*hwater)*hinv;
163  cff2_w=(cff_w+cff1_w*hwater)*hinv;
164 
165  if(k==0) {
166  // HACK: should actually be the normal expression with coeffs evaluated at k=N-1
167  z_w(i,j,N-1)=Zt_avg1(i,j,0);
168 
169  } else if (k==-1) {
170  h(i,j,0,1) = Zt_avg1(i,j,0)+(Zt_avg1(i,j,0)+hwater)*cff2_w;
171 
172  } else {
173  z_w(i,j,k-1)=Zt_avg1(i,j,0)+(Zt_avg1(i,j,0)+hwater)*cff2_w;
174 
175  }
176 
177  if(k!=-1) {
178  z_r(i,j,k)=Zt_avg1(i,j,0)+(Zt_avg1(i,j,0)+hwater)*cff2_r;
179  }
180  } // k
181  });
182 
183  Gpu::streamSynchronize();
184 
185  amrex::ParallelFor(gbx3, [=] AMREX_GPU_DEVICE (int i, int j, int k)
186  {
187  if (k==0) {
188  Hz(i,j,k)=z_w(i,j,k)+h(i,j,0);
189  } else {
190  Hz(i,j,k)=z_w(i,j,k)-z_w(i,j,k-1);
191  }
192  });
193  } // mfi
194 
195  Real time = t_new[lev];
196  FillPatch(lev, time, *vec_z_w[lev], GetVecOfPtrs(vec_z_w));
197  FillPatch(lev, time, *vec_z_r[lev], GetVecOfPtrs(vec_z_r));
198  FillPatch(lev, time, *vec_s_r[lev], GetVecOfPtrs(vec_s_r));
199  FillPatch(lev, time, *vec_Hz[lev] , GetVecOfPtrs(vec_Hz));
200 
201  // Define nodal z as average of z on w-faces
202  for ( MFIter mfi(*cons_new[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi )
203  {
204  Array4<Real> const& z_w = (mf_z_w)->array(mfi);
205  Array4<Real> const& z_phys_nd = (mf_z_phys_nd)->array(mfi);
206 
207  Box z_w_box = Box(z_w);
208  auto const lo = amrex::lbound(z_w_box);
209  auto const hi = amrex::ubound(z_w_box);
210 
211  //
212  // WARNING: z_w(i,j,k) refers to the face on the HIGH side of cell (i,j,k)
213  // WARNING: z_phys_nd(i,j,k) refers to the node on the LOW side of cell (i,j,k)
214  //
215  ParallelFor(Box(z_phys_nd), [=] AMREX_GPU_DEVICE (int i, int j, int k)
216  {
217  // For now assume all boundaries are constant height --
218  // we will enforce periodicity below
219  int kk = (k == 0) ? hi.z : k-1;
220  if ( i >= lo.x && i <= hi.x-1 && j >= lo.y && j <= hi.y-1 )
221  {
222  z_phys_nd(i,j,k)=0.25*( z_w(i,j ,kk) + z_w(i+1,j ,kk) +
223  z_w(i,j+1,kk) + z_w(i+1,j+1,kk) );
224  } else {
225  int ii = std::min(std::max(i, lo.x), hi.x);
226  int jj = std::min(std::max(j, lo.y), hi.y);
227  z_phys_nd(i,j,k) = z_w(ii,jj,kk);
228  }
229  if (k == 0) z_phys_nd(i,j,k) *= -1.;
230  });
231  } // mf
232 
233  // Note that we do *not* want to do a multilevel fill here -- we have
234  // already filled z_phys_nd on the grown boxes, but we enforce periodicity just in case
235  vec_z_phys_nd[lev]->FillBoundary(geom[lev].periodicity());
236 }
amrex::Real theta_b
Definition: DataStruct.H:215
amrex::Real theta_s
Definition: DataStruct.H:214
amrex::Real tcline
Definition: DataStruct.H:216

◆ sum_integrated_quantities()

void REMORA::sum_integrated_quantities ( amrex::Real  time)

Integrate conserved quantities for diagnostics

10 {
11  BL_PROFILE("REMORA::sum_integrated_quantities()");
12 
13  if (verbose <= 0)
14  return;
15 
16  int datwidth = 14;
17  int datprecision = 6;
18 
19  Real scalar = 0.0;
20  Real kineng = 0.0;
21 
22  for (int lev = 0; lev <= finest_level; lev++)
23  {
24  MultiFab kineng_mf(grids[lev], dmap[lev], 1, 0);
25  MultiFab cc_vel_mf(grids[lev], dmap[lev], 3, 0);
26  average_face_to_cellcenter(cc_vel_mf,0,
27  Array<const MultiFab*,3>{xvel_new[lev],yvel_new[lev],zvel_new[lev]});
28 
29  for (MFIter mfi(*cons_new[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi) {
30  const Box& bx = mfi.tilebox();
31  const Array4< Real> kineng_arr = kineng_mf.array(mfi);
32  const Array4<const Real> vel_arr = cc_vel_mf.const_array(mfi);
33  ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
34  {
35  kineng_arr(i,j,k) = 0.5 * ( vel_arr(i,j,k,0)*vel_arr(i,j,k,0) + vel_arr(i,j,k,1)*vel_arr(i,j,k,1) +
36  vel_arr(i,j,k,2)*vel_arr(i,j,k,2) );
37  });
38  } // mfi
39 
40  scalar += volWgtSumMF(lev,*cons_new[lev],Scalar_comp,false,true);
41  kineng += volWgtSumMF(lev,kineng_mf , 0,false,true);
42  }
43 
44  if (verbose > 0) {
45  const int nfoo = 2;
46  Real foo[nfoo] = {scalar,kineng};
47 #ifdef AMREX_LAZY
48  Lazy::QueueReduction([=]() mutable {
49 #endif
50  ParallelDescriptor::ReduceRealSum(
51  foo, nfoo, ParallelDescriptor::IOProcessorNumber());
52 
53  if (ParallelDescriptor::IOProcessor()) {
54  int i = 0;
55  scalar = foo[i++];
56  kineng = foo[i++];
57 
58  amrex::Print() << '\n';
59  amrex::Print() << "TIME= " << time << " SCALAR = " << scalar << '\n';
60  amrex::Print() << "TIME= " << time << " KIN. ENG. = " << kineng << '\n';
61 
62  if (NumDataLogs() > 0) {
63  std::ostream& data_log1 = DataLog(0);
64  if (data_log1.good()) {
65  if (time == 0.0) {
66  data_log1 << std::setw(datwidth) << " time";
67  data_log1 << std::setw(datwidth) << " scalar";
68  data_log1 << std::setw(datwidth) << " kineng";
69  data_log1 << std::endl;
70  }
71 
72  // Write the quantities at this time
73  data_log1 << std::setw(datwidth) << time;
74  data_log1 << std::setw(datwidth) << std::setprecision(datprecision)
75  << scalar;
76  data_log1 << std::setw(datwidth) << std::setprecision(datprecision)
77  << kineng;
78  data_log1 << std::endl;
79  }
80  }
81  }
82 #ifdef AMREX_LAZY
83  });
84 #endif
85  }
86 }
AMREX_FORCE_INLINE std::ostream & DataLog(int i)
Definition: REMORA.H:924
AMREX_FORCE_INLINE int NumDataLogs() noexcept
Definition: REMORA.H:931
amrex::Real volWgtSumMF(int lev, const amrex::MultiFab &mf, int comp, bool local, bool finemask)
Definition: REMORA_SumIQ.cpp:89

◆ t3dmix()

void REMORA::t3dmix ( const amrex::Box &  bx,
const amrex::Array4< amrex::Real > &  state,
const amrex::Array4< amrex::Real const > &  diff2,
const amrex::Array4< amrex::Real const > &  Hz,
const amrex::Array4< amrex::Real const > &  pm,
const amrex::Array4< amrex::Real const > &  pn,
const amrex::Real  dt_lev,
const int  ncomp 
)

Harmonic diffusivity for tracers

13 {
14  //-----------------------------------------------------------------------
15  // Add in harmonic diffusivity s terms.
16  //-----------------------------------------------------------------------
17 
18  Box xbx(bx); xbx.surroundingNodes(0);
19  Box ybx(bx); ybx.surroundingNodes(1);
20 
21  FArrayBox fab_FX(xbx,ncomp,The_Async_Arena());
22  FArrayBox fab_FE(ybx,ncomp,The_Async_Arena());
23 
24  auto FX=fab_FX.array();
25  auto FE=fab_FE.array();
26 
27  ParallelFor(xbx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n)
28  {
29  const Real pmon_u = (pm(i-1,j,0)+pm(i,j,0))/(pn(i-1,j,0)+pn(i,j,0));
30 
31  const Real cff = 0.25 * (diff2(i,j,n) + diff2(i-1,j,n)) * pmon_u;
32  FX(i,j,k,n) = cff * (Hz(i,j,k) + Hz(i+1,j,k)) * (state(i,j,k,n)-state(i-1,j,k,n));
33  });
34 
35  ParallelFor(ybx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n)
36  {
37  const Real pnom_v = (pn(i,j-1,0)+pn(i,j,0))/(pm(i,j-1,0)+pm(i,j,0));
38 
39  const Real cff = 0.25*(diff2(i,j,n)+diff2(i,j-1,n)) * pnom_v;
40  FE(i,j,k,n) = cff * (Hz(i,j,k) + Hz(i,j-1,k)) * (state(i,j,k,n) - state(i,j-1,k,n));
41  });
42 
43  /*
44  Time-step harmonic, S-surfaces diffusion term.
45  */
46  ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n)
47  {
48  const Real cff = dt_lev*pm(i,j,0)*pn(i,j,0);
49 
50  state(i,j,k,n) += cff * ( (FX(i+1,j ,k,n)-FX(i,j,k,n))
51  +(FE(i ,j+1,k,n)-FE(i,j,k,n)) );
52  });
53 }

◆ timeStep()

void REMORA::timeStep ( int  lev,
amrex::Real  time,
int  iteration 
)
private

advance a level by dt, includes a recursive call for finer levels

10 {
11  if (regrid_int > 0) // We may need to regrid
12  {
13  // help keep track of whether a level was already regridded
14  // from a coarser level call to regrid
15  static Vector<int> last_regrid_step(max_level+1, 0);
16 
17  // regrid changes level "lev+1" so we don't regrid on max_level
18  // also make sure we don't regrid fine levels again if
19  // it was taken care of during a coarser regrid
20  if (lev < max_level && istep[lev] > last_regrid_step[lev])
21  {
22  if (istep[lev] % regrid_int == 0)
23  {
24  // regrid could add newly refine levels (if finest_level < max_level)
25  // so we save the previous finest level index
26  int old_finest = finest_level;
27  regrid(lev, time);
28 
29  // Mark that we have regridded this level already
30  for (int k = lev; k <= finest_level; ++k) {
31  last_regrid_step[k] = istep[k];
32  }
33 
34  // If there are newly created levels, set the time step
35  for (int k = old_finest+1; k <= finest_level; ++k) {
36  dt[k] = dt[k-1] / MaxRefRatio(k-1);
37  }
38  }
39  }
40  }
41  // Update what we call "old" and "new" time
42  t_old[lev] = t_new[lev];
43  t_new[lev] += dt[lev];
44 
45  if (Verbose()) {
46  amrex::Print() << "[Level " << lev << " step " << istep[lev]+1 << "] ";
47  amrex::Print() << "ADVANCE from time = " << t_old[lev] << " to " << t_new[lev]
48  << " with dt = " << dt[lev] << std::endl;
49  }
50 
51  // We must swap the pointers so the previous step's "new" is now this step's "old"
52  std::swap(cons_old[lev], cons_new[lev]);
53  std::swap(xvel_old[lev], xvel_new[lev]);
54  std::swap(yvel_old[lev], yvel_new[lev]);
55  std::swap(zvel_old[lev], zvel_new[lev]);
56 
57  // Advance a single level for a single time step
58  Advance(lev, time, dt[lev], iteration, nsubsteps[lev]);
59 
60  ++istep[lev];
61 
62  if (Verbose())
63  {
64  amrex::Print() << "[Level " << lev << " step " << istep[lev] << "] ";
65  amrex::Print() << "Advanced " << CountCells(lev) << " cells" << std::endl;
66  }
67 
68  if (lev < finest_level)
69  {
70  // recursive call for next-finer level
71  for (int i = 1; i <= nsubsteps[lev+1]; ++i)
72  {
73  timeStep(lev+1, time+(i-1)*dt[lev+1], i);
74  }
75 
77  AverageDownTo(lev); // average lev+1 down to lev
78  }
79  }
80 }
void Advance(int lev, amrex::Real time, amrex::Real dt_lev, int iteration, int ncycle)
Definition: REMORA_Advance.cpp:7

◆ timeStepML()

void REMORA::timeStepML ( amrex::Real  time,
int  iteration 
)
private

advance all levels by dt, loops over finer levels

10 {
11  // HACK HACK so lev is defined and compiler won't complain, but always say regrid_int=-1
12  for (int lev=0; lev <= finest_level;lev++) {
13  if (regrid_int > 0) // We may need to regrid
14  {
15  // help keep track of whether a level was already regridded
16  // from a coarser level call to regrid
17  static Vector<int> last_regrid_step(max_level+1, 0);
18 
19  // regrid changes level "lev+1" so we don't regrid on max_level
20  // also make sure we don't regrid fine levels again if
21  // it was taken care of during a coarser regrid
22  if (lev < max_level && istep[lev] > last_regrid_step[lev])
23  {
24  if (istep[lev] % regrid_int == 0)
25  {
26  // regrid could add newly refine levels (if finest_level < max_level)
27  // so we save the previous finest level index
28  int old_finest = finest_level;
29  regrid(lev, time);
30 
31  // Mark that we have regridded this level already
32  for (int k = lev; k <= finest_level; ++k) {
33  last_regrid_step[k] = istep[k];
34  }
35 
36  // If there are newly created levels, set the time step
37  for (int k = old_finest+1; k <= finest_level; ++k) {
38  dt[k] = dt[k-1] / MaxRefRatio(k-1);
39  }
40  }
41  }
42  }
43  }
44 
45  for (int lev=0; lev <= finest_level;lev++)
46  {
47  // Update what we call "old" and "new" time
48  t_old[lev] = t_new[lev];
49  t_new[lev] += dt[lev];
50 
51  if (Verbose()) {
52  amrex::Print() << "[Level " << lev << " step " << istep[lev]+1 << "] ";
53  amrex::Print() << "ADVANCE from time = " << t_old[lev] << " to " << t_new[lev]
54  << " with dt = " << dt[lev] << std::endl;
55  }
56 
57  // We must swap the pointers so the previous step's "new" is now this step's "old"
58  std::swap(cons_old[lev], cons_new[lev]);
59  std::swap(xvel_old[lev], xvel_new[lev]);
60  std::swap(yvel_old[lev], yvel_new[lev]);
61  std::swap(zvel_old[lev], zvel_new[lev]);
62 
63  setup_step(lev, time, dt[lev]);
64  }
65 
67  {
68  int nfast_counter=nfast + 1;
69 
70  for (int lev=0; lev <= finest_level; lev++)
71  {
72  //Compute fast timestep from dt_lev and ratio
73  Real dtfast_lev=dt[lev]/Real(fixed_ndtfast_ratio);
74  for (int my_iif = 0; my_iif < nfast_counter; my_iif++) {
75  advance_2d_onestep(lev, dt[lev], dtfast_lev, my_iif, nfast_counter);
76  } // my_iif
77  } // lev
78  } // use_barotropic
79 
80  for (int lev=0; lev <= finest_level; lev++) {
81  advance_3d_ml(lev, dt[lev]);
82  ++istep[lev];
83 
84  if (Verbose())
85  {
86  amrex::Print() << "[Level " << lev << " step " << istep[lev] << "] ";
87  amrex::Print() << "Advanced " << CountCells(lev) << " cells" << std::endl;
88  }
89  }
90 
92  for (int lev=0; lev <= finest_level-1; lev++) {
93  AverageDownTo(lev); // average lev+1 down to lev
94  }
95  }
96 }

◆ update_massflux_3d()

void REMORA::update_massflux_3d ( const amrex::Box &  bx,
const int  ioff,
const int  joff,
const amrex::Array4< amrex::Real > &  phi,
const amrex::Array4< amrex::Real > &  phibar,
const amrex::Array4< amrex::Real > &  Hphi,
const amrex::Array4< amrex::Real const > &  Hz,
const amrex::Array4< amrex::Real const > &  pm_or_pn,
const amrex::Array4< amrex::Real const > &  Dphi1,
const amrex::Array4< amrex::Real const > &  Dphi2,
const amrex::Array4< amrex::Real > &  DC,
const amrex::Array4< amrex::Real > &  FC,
const int  nnew 
)

update_massflux_3d

Parameters
[in]bxbox on which to update
[in]ioffoffset in x-direction
[in]joffoffset in y-direction
[in]phiu or v
[out]HphiH-weighted u or v
[in]Hzweighting
[in]om_v_or_on_u
[in]Dphi_avg1
[in]Dphi_avg2
[in,out]DC
[in,out]FC
[in]nnewcomponent of velocity
35 {
36  auto N = Geom(0).Domain().size()[2]-1; // Number of vertical "levs" aka, NZ
37 
38  auto bxD=bx;
39  auto bx_g1z=bx;
40  bxD.makeSlab(2,0);
41  bx_g1z.grow(IntVect(0,0,1));
42 
43  // auto geomdata = Geom(0).data();
44  // bool NSPeriodic = geomdata.isPeriodic(1);
45  // bool EWPeriodic = geomdata.isPeriodic(0);
46 
47  //Copied depth of water column calculation from DepthStretchTransform
48  //Compute thicknesses of U-boxes DC(i,j,0:N-1), total depth of the water column DC(i,j,-1)
49 
50  //This takes advantage of Hz being an extra grow cell size
51  ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
52  {
53  Real om_v_or_on_u = 2.0_rt / (pm_or_pn(i,j,0) + pm_or_pn(i-ioff,j-joff,0));
54 
55  DC(i,j,k) = 0.5_rt * om_v_or_on_u * (Hz(i,j,k)+Hz(i-ioff,j-joff,k));
56  });
57 
58  ParallelFor(bxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
59  {
60  for (int k=0; k<=N; k++) {
61  DC(i,j,-1) += DC(i,j,k);
62  }
63 
64  DC(i,j,-1) = 1.0 / DC(i,j,-1);
65 
66  for (int k=0; k<=N; k++) {
67 
68 // BOUNDARY CONDITIONS
69 // if (!(NSPeriodic&&EWPeriodic))
70 // {
71 // if ( ( ((i<0)||(i>=Mn+1)) && !EWPeriodic ) || ( ((j<0)||(j>=Mm+1)) && !NSPeriodic ) )
72 // {
73 // phi(i,j,k) -= CF;
74 // }
75 // }
76 
77  Hphi(i,j,k) = 0.5 * (Hphi(i,j,k)+phi(i,j,k,nnew)*DC(i,j,k));
78  FC(i,j,0) += Hphi(i,j,k);
79  } // k
80 
81  FC(i,j,0) = DC(i,j,-1)*(FC(i,j,0)-Dphi_avg2(i,j,0));
82  });
83 
84  ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
85  {
86  Hphi(i,j,k) -= DC(i,j,k)*FC(i,j,0);
87  });
88 
89  ParallelFor(bxD, [=] AMREX_GPU_DEVICE(int i, int j, int )
90  {
91  phibar(i,j,0,0) = DC(i,j,-1) * Dphi_avg1(i,j,0);
92  phibar(i,j,0,1) = phibar(i,j,0,0);
93  });
94 
95 }

◆ uv3dmix()

void REMORA::uv3dmix ( const amrex::Box &  xbx,
const amrex::Box &  ybx,
const amrex::Array4< amrex::Real > &  u,
const amrex::Array4< amrex::Real > &  v,
const amrex::Array4< amrex::Real const > &  uold,
const amrex::Array4< amrex::Real const > &  vold,
const amrex::Array4< amrex::Real > &  rufrc,
const amrex::Array4< amrex::Real > &  rvfrc,
const amrex::Array4< amrex::Real const > &  visc2_p,
const amrex::Array4< amrex::Real const > &  visc2_r,
const amrex::Array4< amrex::Real const > &  Hz,
const amrex::Array4< amrex::Real const > &  pm,
const amrex::Array4< amrex::Real const > &  pn,
int  nrhs,
int  nnew,
const amrex::Real  dt_lev 
)

Harmonic viscosity

20 {
21  //-----------------------------------------------------------------------
22  // Add in harmonic viscosity s terms.
23  //-----------------------------------------------------------------------
24 
25  FArrayBox fab_UFx(growLo(xbx,0,1),1,amrex::The_Async_Arena()); fab_UFx.template setVal<RunOn::Device>(0.);
26  FArrayBox fab_UFe(growHi(xbx,1,1),1,amrex::The_Async_Arena()); fab_UFe.template setVal<RunOn::Device>(0.);
27  FArrayBox fab_VFe(growLo(ybx,1,1),1,amrex::The_Async_Arena()); fab_VFe.template setVal<RunOn::Device>(0.);
28  FArrayBox fab_VFx(growHi(ybx,0,1),1,amrex::The_Async_Arena()); fab_VFx.template setVal<RunOn::Device>(0.);
29 
30  auto UFx=fab_UFx.array();
31  auto UFe=fab_UFe.array();
32  auto VFx=fab_VFx.array();
33  auto VFe=fab_VFe.array();
34 
35  // Think of the cell-centered box as [ 0:nx-1, 0:ny-1] (0,0,0) cc
36  //
37  // xbx is the x-face-centered box on which we update u [ 0:nx , 0:ny-1] (1,0,0) x-faces
38  // to do so requires UFx on [-1:nx , 0:ny-1] (0,0,0) cc
39  // which requires uold on [-1:nx+1, 0:ny-1] (1,0,0) x-faces
40  // and requires vold on [-1:nx , 0:ny ] (0,1,0) y-faces
41  // to do so requires UFe on [ 0:nx , 0:ny ] (1,1,0) xy-nodes
42  // which requires uold on [ 0:nx ,-1:ny ] (1,0,0) x-faces
43  // and requires vold on [ -1:nx , 0:ny ] (0,1,0) y-faces
44 
45  ParallelFor(growLo(xbx,0,1), [=] AMREX_GPU_DEVICE (int i, int j, int k)
46  {
47  const Real cff = 0.5*Hz(i,j,k) * ( pm(i,j,0) / pn(i,j,0) *
48  ( (pn(i ,j,0) + pn(i+1,j,0)) * uold(i+1,j,k,nrhs)-
49  (pn(i-1,j,0) + pn(i ,j,0)) * uold(i ,j,k,nrhs) )-
50  pn(i,j,0) / pm(i,j,0) *
51  ( (pm(i,j ,0) + pm(i,j+1,0)) * vold(i,j+1,k,nrhs)-
52  (pm(i,j-1,0) + pm(i,j ,0)) * vold(i,j ,k,nrhs) ) );
53 
54  Real on_r = 1.0_rt / pm(i,j,0);
55  UFx(i,j,k) = on_r * on_r * visc2_r(i,j,0) * cff;
56  });
57 
58  ParallelFor(growHi(xbx,1,1), [=] AMREX_GPU_DEVICE (int i, int j, int k)
59  {
60  const Real cff = 0.125 * (Hz(i-1,j ,k) + Hz(i,j ,k)+ Hz(i-1,j-1,k) + Hz(i,j-1,k))*
61  (pm(i,j,0)/pn(i,j,0)*
62  ((pn(i ,j-1,0)+pn(i ,j,0))*vold(i ,j,k,nrhs)-
63  (pn(i-1,j-1,0)+pn(i-1,j,0))*vold(i-1,j,k,nrhs))+
64  pn(i,j,0)/pm(i,j,0)*
65  ((pm(i-1,j ,0)+pm(i,j ,0))*uold(i,j ,k,nrhs)-
66  (pm(i-1,j-1,0)+pm(i,j-1,0))*uold(i,j-1,k,nrhs)));
67 
68  const Real om_p = 4.0_rt / (pm(i-1,j-1,0)+pm(i-1,j,0)+pm(i,j-1,0)+pm(i,j,0));
69  UFe(i,j,k) = om_p*om_p*visc2_p(i,j,0)*cff;
70  });
71 
72  ParallelFor(xbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
73  {
74  const Real cff=dt_lev*0.25*(pm(i-1,j,0)+pm(i,j,0))*(pn(i-1,j,0)+pn(i,j,0));
75  const Real cff1=0.5*(pn(i-1,j,0)+pn(i,j,0))*(UFx(i,j ,k)-UFx(i-1,j,k));
76  const Real cff2=0.5*(pm(i-1,j,0)+pm(i,j,0))*(UFe(i,j+1,k)-UFe(i ,j,k));
77  const Real cff3=cff*(cff1+cff2);
78  amrex::Gpu::Atomic::Add(&(rufrc(i,j,0)), cff1+cff2);
79  u(i,j,k,nnew)=u(i,j,k,nnew)+cff3;
80  });
81 
82 
83  // Think of the cell-centered box as [ 0:nx-1, 0:ny-1] (0,0,0) cc
84  //
85  // ybx is the y-face-centered box on which we update v [ 0:nx-1, 0:ny ] (1,0,0) x-faces
86  // to do so requires VFe on [ 0:nx-1,-1:ny ] (0,0,0) cc
87  // which requires uold on [ 0:nx ,-1:ny ] (1,0,0) x-faces
88  // and requires vold on [ 0:nx-1,-1:ny+1] (0,1,0) y-faces
89  // to do so requires VFx on [ 0:nx , 0:ny ] (1,1,0) xy-nodes
90  // which requires uold on [ 0:nx ,-1:ny ] (1,0,0) x-faces
91  // and requires vold on [-1:nx , 0:ny ] (0,1,0) y-faces
92 
93  ParallelFor(growLo(ybx,1,1), [=] AMREX_GPU_DEVICE (int i, int j, int k)
94  {
95  // cff depends on k, but UFx and VFe will only be affected by the last cell?
96  const Real cff = 0.5*Hz(i,j,k) * (pm(i,j,0) / pn(i,j,0) *
97  ((pn(i, j,0) + pn(i+1,j,0)) * uold(i+1,j,k,nrhs)-
98  (pn(i-1,j,0) + pn(i, j,0)) * uold(i ,j,k,nrhs))-
99  pn(i,j,0) / pm(i,j,0) *
100  ((pm(i,j ,0)+pm(i,j+1,0))*vold(i,j+1,k,nrhs)-
101  (pm(i,j-1,0)+pm(i,j ,0))*vold(i,j ,k,nrhs)));
102 
103  Real om_r = 1.0_rt / pm(i,j,0);
104  VFe(i,j,k) = om_r * om_r * visc2_r(i,j,0) * cff;
105  });
106 
107  ParallelFor(growHi(ybx,0,1), [=] AMREX_GPU_DEVICE (int i, int j, int k)
108  {
109  const Real cff = 0.125 * (Hz(i-1,j ,k)+Hz(i,j ,k)+
110  Hz(i-1,j-1,k)+Hz(i,j-1,k))*
111  (pm(i,j,0)/pn(i,j,0)*
112  ((pn(i ,j-1,0)+pn(i ,j,0))*vold(i ,j,k,nrhs)-
113  (pn(i-1,j-1,0)+pn(i-1,j,0))*vold(i-1,j,k,nrhs))+
114  pn(i,j,0)/pm(i,j,0)*
115  ((pm(i-1,j ,0)+pm(i,j ,0))*uold(i,j ,k,nrhs)-
116  (pm(i-1,j-1,0)+pm(i,j-1,0))*uold(i,j-1,k,nrhs)));
117 
118  const Real on_p = 4.0_rt / (pn(i-1,j-1,0)+pn(i-1,j,0)+pn(i,j-1,0)+pn(i,j,0));
119  VFx(i,j,k) = on_p*on_p*visc2_p(i,j,0)*cff;
120  });
121 
122  ParallelFor(ybx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
123  {
124  const Real cff=dt_lev*0.25*(pm(i,j,0)+pm(i,j-1,0))*(pn(i,j,0)+pn(i,j-1,0));
125  const Real cff1=0.5*(pn(i,j-1,0)+pn(i,j,0))*(VFx(i+1,j,k)-VFx(i,j ,k));
126  const Real cff2=0.5*(pm(i,j-1,0)+pm(i,j,0))*(VFe(i ,j,k)-VFe(i,j-1,k));
127  const Real cff3=cff*(cff1-cff2);
128  amrex::Gpu::Atomic::Add(&(rvfrc(i,j,0)), cff1-cff2);
129  v(i,j,k,nnew)=v(i,j,k,nnew)+cff3;
130  });
131 
132 }

◆ vert_mean_3d()

void REMORA::vert_mean_3d ( const amrex::Box &  bx,
const int  ioff,
const int  joff,
const amrex::Array4< amrex::Real > &  phi,
const amrex::Array4< amrex::Real const > &  Hz,
const amrex::Array4< amrex::Real const > &  Dphi_avg1,
const amrex::Array4< amrex::Real > &  DC,
const amrex::Array4< amrex::Real > &  CF,
const amrex::Array4< amrex::Real const > &  dxlen,
const int  nnew,
const int  N 
)
18 {
19 
20  ParallelFor(makeSlab(phi_bx,2,0),
21  [=] AMREX_GPU_DEVICE (int i, int j, int )
22  {
23  Real Hzk_on_face = 0.5*(Hz(i-ioff,j-joff,0)+Hz(i,j,0));
24  CF(i,j,-1) = Hzk_on_face;
25  DC(i,j,-1) = phi(i,j,0,nnew)*Hzk_on_face;
26 
27  for (int k=1; k<=N; k++) {
28  Hzk_on_face = 0.5*(Hz(i-ioff,j-joff,k)+Hz(i,j,k));
29  CF(i,j,-1) += Hzk_on_face;
30  DC(i,j,-1) += phi(i,j,k,nnew)*Hzk_on_face;
31  }
32  });
33 
34  ParallelFor(makeSlab(phi_bx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
35  {
36  Real cff1=1.0/(CF(i,j,-1)*(1.0/dxlen(i,j,0)));
37  DC(i,j,-1) = (DC(i,j,-1)*(1.0/dxlen(i,j,0)) - Dphi_avg1(i,j,0))*cff1; // recursive
38  });
39 
40  ParallelFor(phi_bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
41  {
42  phi(i,j,k) -= DC(i,j,-1);
43  });
44 }

◆ vert_visc_3d()

void REMORA::vert_visc_3d ( const amrex::Box &  bx,
const int  ioff,
const int  joff,
const amrex::Array4< amrex::Real > &  phi,
const amrex::Array4< amrex::Real const > &  Hz,
const amrex::Array4< amrex::Real > &  Hzk,
const amrex::Array4< amrex::Real > &  AK,
const amrex::Array4< amrex::Real > &  Akv,
const amrex::Array4< amrex::Real > &  BC,
const amrex::Array4< amrex::Real > &  DC,
const amrex::Array4< amrex::Real > &  FC,
const amrex::Array4< amrex::Real > &  CF,
const int  nnew,
const int  N,
const amrex::Real  dt_lev 
)
21 {
22  //
23  // Put Hzk on the x- or y-face as appropriate, or leave on cell center for tracers
24  //
25  if (verbose > 1)
26  amrex::Print() << "updating on box in vert_visc_3d: " << phi_bx << std::endl;
27 
28  ParallelFor(phi_bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
29  {
30  Hzk(i,j,k)=0.5*(Hz(i-ioff,j-joff,k)+Hz(i,j,k));
31  });
32 
33  //
34  // Put Akv on the x- or y-face as appropriate, or leave on cell center for tracers
35  //
36  ParallelFor(phi_bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
37  {
38  AK(i,j,k) = 0.5 * (Akv(i-ioff,j-joff,k)+Akv(i,j,k));
39  });
40 
41  Gpu::streamSynchronize();
42 #ifdef AMREX_USE_GPU
43  Gpu::synchronize();
44 #else
45 #endif
46  /////////////////// This and the following loop is the first non-matching thing that affects plotfile comparison for cuda
47  // NOTE: vertical viscosity term for tracers is identical except AK=Akt
48  const Real sixth = 1.0_rt / 6.0_rt;
49  const Real third = 1.0_rt / 3.0_rt;
50 
51  ParallelFor(makeSlab(phi_bx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
52  {
53  for (int k=0; k<=N; k++)
54  {
55  //
56  // Use conservative, parabolic spline reconstruction of vertical
57  // viscosity derivatives. Then, time step vertical viscosity term
58  // implicitly by solving a tridiagonal system.
59  //
60  Real cff;
61 
62  const Real oHz = 1.0/ Hzk(i,j,k);
63 
64  FC(i,j,k) = (k >= 1) ? sixth*Hzk(i,j,k )-dt_lev*AK(i,j,k-1)*oHz :
65  sixth*Hzk(i,j,k);
66 
67  if (k < N)
68  {
69  const Real oHzkp1 = 1.0/ Hzk(i,j,k+1);
70 
71  CF(i,j,k)=sixth*Hzk(i,j,k+1)-dt_lev*AK(i,j,k+1)*oHzkp1;
72 
73  if (k==0)
74  {
75  BC(i,j,k)=third*(Hzk(i,j,k)+Hzk(i,j,k+1)) + dt_lev*AK(i,j,k)*(oHz+oHzkp1);
76 
77  cff=1.0/(BC(i,j,k)-FC(i,j,k)*0.0);
78  CF(i,j,k) *= cff;
79  DC(i,j,k) = cff*(phi(i,j,k+1,nnew)-phi(i,j,k,nnew)-FC(i,j,k)*0.0);
80 
81  } else {
82 
83  BC(i,j,k)=third*(Hzk(i,j,k)+Hzk(i,j,k+1)) + dt_lev*AK(i,j,k)*(oHz+oHzkp1);
84  cff=1.0/(BC(i,j,k)-FC(i,j,k)*CF(i,j,k-1));
85  CF(i,j,k) *= cff;
86  DC(i,j,k) = cff*(phi(i,j,k+1,nnew)-phi(i,j,k,nnew)-FC(i,j,k)*DC(i,j,k-1));
87  }
88  } // k < N
89  } // k
90  });
91 #ifdef AMREX_USE_GPU
92  Gpu::synchronize();
93 #else
94 #endif
95  Gpu::streamSynchronize();
96  ParallelFor(makeSlab(phi_bx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
97  {
98  for(int k=0; k<=N; k++) {
99  //
100  // Backward substitution.
101  //
102  DC(i,j,N)=0.0;
103 
104  if(N-k+1<=N && N>=k) //-N,1,-1 => kidx =N-k+1
105  {
106  if(N+1<k || N+2<k) amrex::Abort("-1 here");
107  DC(i,j,N-k) -= CF(i,j,N-k)*DC(i,j,N-k+1);
108  }
109  }
110  });
111 
112 #ifdef AMREX_USE_GPU
113  Gpu::synchronize();
114 #endif
115 
116  ParallelFor(phi_bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
117  {
118  DC(i,j,k) *= AK(i,j,k);
119  });
120 
121  ParallelFor(phi_bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
122  {
123  Real cff;
124  if(k-1>=0) {
125  const Real oHz = 1.0/ Hzk(i,j,k);
126  cff = dt_lev*oHz*(DC(i,j,k)-DC(i,j,k-1));
127  } else {
128  const Real oHz = 1.0/ Hzk(i,j,k);
129  cff = dt_lev*oHz*(DC(i,j,k));
130  }
131  phi(i,j,k) += cff;
132  });
133 }

◆ volWgtSumMF()

Real REMORA::volWgtSumMF ( int  lev,
const amrex::MultiFab &  mf,
int  comp,
bool  local,
bool  finemask 
)
90 {
91  BL_PROFILE("REMORA::volWgtSumMF()");
92 
93  Real sum = 0.0;
94  MultiFab tmp(grids[lev], dmap[lev], 1, 0);
95  MultiFab::Copy(tmp, mf, comp, 0, 1, 0);
96 
97  if (lev < finest_level && finemask) {
98  const MultiFab& mask = build_fine_mask(lev+1);
99  MultiFab::Multiply(tmp, mask, 0, 0, 1, 0);
100  }
101 
102  MultiFab volume(grids[lev], dmap[lev], 1, 0);
103  auto const& dx = geom[lev].CellSizeArray();
104  Real cell_vol = dx[0]*dx[1]*dx[2];
105  volume.setVal(cell_vol);
106  sum = MultiFab::Dot(tmp, 0, volume, 0, 1, 0, local);
107 
108  if (!local)
109  ParallelDescriptor::ReduceRealSum(sum);
110 
111  return sum;
112 }
amrex::MultiFab & build_fine_mask(int lev)
Definition: REMORA_SumIQ.cpp:115

◆ writeBuildInfo()

void REMORA::writeBuildInfo ( std::ostream &  os)
static
136 {
137  std::string PrettyLine = std::string(78, '=') + "\n";
138  std::string OtherLine = std::string(78, '-') + "\n";
139  std::string SkipSpace = std::string(8, ' ');
140 
141  // build information
142  os << PrettyLine;
143  os << " REMORA Build Information\n";
144  os << PrettyLine;
145 
146  os << "build date: " << amrex::buildInfoGetBuildDate() << "\n";
147  os << "build machine: " << amrex::buildInfoGetBuildMachine() << "\n";
148  os << "build dir: " << amrex::buildInfoGetBuildDir() << "\n";
149  os << "AMReX dir: " << amrex::buildInfoGetAMReXDir() << "\n";
150 
151  os << "\n";
152 
153  os << "COMP: " << amrex::buildInfoGetComp() << "\n";
154  os << "COMP version: " << amrex::buildInfoGetCompVersion() << "\n";
155 
156  os << "C++ compiler: " << amrex::buildInfoGetCXXName() << "\n";
157  os << "C++ flags: " << amrex::buildInfoGetCXXFlags() << "\n";
158 
159  os << "\n";
160 
161  os << "Link flags: " << amrex::buildInfoGetLinkFlags() << "\n";
162  os << "Libraries: " << amrex::buildInfoGetLibraries() << "\n";
163 
164  os << "\n";
165 
166  for (int n = 1; n <= amrex::buildInfoGetNumModules(); n++) {
167  os << amrex::buildInfoGetModuleName(n) << ": "
168  << amrex::buildInfoGetModuleVal(n) << "\n";
169  }
170 
171  os << "\n";
172  const char* githash1 = amrex::buildInfoGetGitHash(1);
173  const char* githash2 = amrex::buildInfoGetGitHash(2);
174  if (strlen(githash1) > 0) {
175  os << "REMORA git hash: " << githash1 << "\n";
176  }
177  if (strlen(githash2) > 0) {
178  os << "AMReX git hash: " << githash2 << "\n";
179  }
180 
181  const char* buildgithash = amrex::buildInfoGetBuildGitHash();
182  const char* buildgitname = amrex::buildInfoGetBuildGitName();
183  if (strlen(buildgithash) > 0) {
184  os << buildgitname << " git hash: " << buildgithash << "\n";
185  }
186 
187  os << "\n";
188  os << " REMORA Compile time variables: \n";
189 
190  os << "\n";
191  os << " REMORA Defines: \n";
192 #ifdef _OPENMP
193  os << std::setw(35) << std::left << "_OPENMP " << std::setw(6) << "ON"
194  << std::endl;
195 #else
196  os << std::setw(35) << std::left << "_OPENMP " << std::setw(6) << "OFF"
197  << std::endl;
198 #endif
199 
200 #ifdef MPI_VERSION
201  os << std::setw(35) << std::left << "MPI_VERSION " << std::setw(6)
202  << MPI_VERSION << std::endl;
203 #else
204  os << std::setw(35) << std::left << "MPI_VERSION " << std::setw(6)
205  << "UNDEFINED" << std::endl;
206 #endif
207 
208 #ifdef MPI_SUBVERSION
209  os << std::setw(35) << std::left << "MPI_SUBVERSION " << std::setw(6)
210  << MPI_SUBVERSION << std::endl;
211 #else
212  os << std::setw(35) << std::left << "MPI_SUBVERSION " << std::setw(6)
213  << "UNDEFINED" << std::endl;
214 #endif
215 
216  os << "\n\n";
217 }

Referenced by main().

Here is the caller graph for this function:

◆ WriteCheckpointFile()

void REMORA::WriteCheckpointFile ( ) const
private
16 {
17  // chk00010 write a checkpoint file with this root directory
18  // chk00010/Header this contains information you need to save (e.g., finest_level, t_new, etc.) and also
19  // the BoxArrays at each level
20  // chk00010/Level_0/
21  // chk00010/Level_1/
22  // etc. these subdirectories will hold the MultiFab data at each level of refinement
23 
24  // checkpoint file name, e.g., chk00010
25  const std::string& checkpointname = amrex::Concatenate(check_file,istep[0],5);
26 
27  amrex::Print() << "Writing checkpoint " << checkpointname << "\n";
28 
29  const int nlevels = finest_level+1;
30 
31  // ---- prebuild a hierarchy of directories
32  // ---- dirName is built first. if dirName exists, it is renamed. then build
33  // ---- dirName/subDirPrefix_0 .. dirName/subDirPrefix_nlevels-1
34  // ---- if callBarrier is true, call ParallelDescriptor::Barrier()
35  // ---- after all directories are built
36  // ---- ParallelDescriptor::IOProcessor() creates the directories
37  amrex::PreBuildDirectorHierarchy(checkpointname, "Level_", nlevels, true);
38 
39  // write Header file
40  if (ParallelDescriptor::IOProcessor()) {
41 
42  std::string HeaderFileName(checkpointname + "/Header");
43  VisMF::IO_Buffer io_buffer(VisMF::IO_Buffer_Size);
44  std::ofstream HeaderFile;
45  HeaderFile.rdbuf()->pubsetbuf(io_buffer.dataPtr(), io_buffer.size());
46  HeaderFile.open(HeaderFileName.c_str(), std::ofstream::out |
47  std::ofstream::trunc |
48  std::ofstream::binary);
49  if( ! HeaderFile.good()) {
50  amrex::FileOpenFailed(HeaderFileName);
51  }
52 
53  HeaderFile.precision(17);
54 
55  // write out title line
56  HeaderFile << "Checkpoint file for REMORA\n";
57 
58  // write out finest_level
59  HeaderFile << finest_level << "\n";
60 
61  // write the number of components
62  // for each variable we store
63 
64  // conservative, cell-centered vars
65  HeaderFile << NCONS << "\n";
66 
67  // x-velocity on faces
68  HeaderFile << 1 << "\n";
69 
70  // y-velocity on faces
71  HeaderFile << 1 << "\n";
72 
73  // z-velocity on faces
74  HeaderFile << 1 << "\n";
75 
76  HeaderFile << 2 << "\n";
77 
78  HeaderFile << 2 << "\n";
79 
80  HeaderFile << 3 << "\n";
81 
82  HeaderFile << 3 << "\n";
83 
84  // write out array of istep
85  for (int i = 0; i < istep.size(); ++i) {
86  HeaderFile << istep[i] << " ";
87  }
88  HeaderFile << "\n";
89 
90  // write out array of dt
91  for (int i = 0; i < dt.size(); ++i) {
92  HeaderFile << dt[i] << " ";
93  }
94  HeaderFile << "\n";
95 
96  // write out array of t_new
97  for (int i = 0; i < t_new.size(); ++i) {
98  HeaderFile << t_new[i] << " ";
99  }
100  HeaderFile << "\n";
101 
102  // write the BoxArray at each level
103  for (int lev = 0; lev <= finest_level; ++lev) {
104  boxArray(lev).writeOn(HeaderFile);
105  HeaderFile << '\n';
106  }
107  }
108 
109  // write the MultiFab data to, e.g., chk00010/Level_0/
110  // Here we make copies of the MultiFab with no ghost cells
111  for (int lev = 0; lev <= finest_level; ++lev)
112  {
113  BoxList bl2d = grids[lev].boxList();
114  for (auto& b : bl2d) {
115  b.setRange(2,0);
116  }
117  BoxArray ba2d(std::move(bl2d));
118 
119  MultiFab cons(grids[lev],dmap[lev],NCONS,0);
120  MultiFab::Copy(cons,*cons_new[lev],0,0,NCONS,0);
121  VisMF::Write(cons, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "Cell"));
122 
123  MultiFab xvel(convert(grids[lev],IntVect(1,0,0)),dmap[lev],1,0);
124  MultiFab::Copy(xvel,*xvel_new[lev],0,0,1,0);
125  VisMF::Write(xvel, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "XFace"));
126 
127  MultiFab yvel(convert(grids[lev],IntVect(0,1,0)),dmap[lev],1,0);
128  MultiFab::Copy(yvel,*yvel_new[lev],0,0,1,0);
129  VisMF::Write(yvel, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "YFace"));
130 
131  MultiFab zvel(convert(grids[lev],IntVect(0,0,1)),dmap[lev],1,0);
132  MultiFab::Copy(zvel,*zvel_new[lev],0,0,1,0);
133  VisMF::Write(zvel, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "ZFace"));
134 
135  MultiFab mf_ru(grids[lev],dmap[lev],2,NGROW);
136  MultiFab::Copy(mf_ru,*vec_ru[lev],0,0,2,NGROW);
137  VisMF::Write(mf_ru, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "XRHS"));
138 
139  MultiFab mf_rv(grids[lev],dmap[lev],2,NGROW);
140  MultiFab::Copy(mf_rv,*vec_rv[lev],0,0,2,NGROW);
141  VisMF::Write(mf_rv, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "YRHS"));
142 
143  MultiFab mf_ubar(ba2d,dmap[lev],3,NGROW);
144  MultiFab::Copy(mf_ubar,*(vec_ubar[lev]),0,0,3,NGROW);
145  VisMF::Write(mf_ubar, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "XBar"));
146 
147  MultiFab mf_vbar(ba2d,dmap[lev],3,NGROW);
148  MultiFab::Copy(mf_vbar,*(vec_vbar[lev]),0,0,3,NGROW);
149  VisMF::Write(mf_vbar, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "YBar"));
150 
151  VisMF::Write(*(vec_rufrc[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "rufrc"));
152  VisMF::Write(*(vec_rvfrc[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "rvfrc"));
153 
154  VisMF::Write(*(vec_sustr[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "sustr"));
155  VisMF::Write(*(vec_svstr[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "svstr"));
156 
157  VisMF::Write(*(vec_rdrag[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "rdrag"));
158 
159  VisMF::Write(*(vec_bustr[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "bustr"));
160  VisMF::Write(*(vec_bvstr[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "bvstr"));
161 
162  VisMF::Write(*(vec_DU_avg1[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "DU_avg1"));
163  VisMF::Write(*(vec_DU_avg2[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "DU_avg2"));
164  VisMF::Write(*(vec_DV_avg1[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "DV_avg1"));
165  VisMF::Write(*(vec_DV_avg2[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "DV_avg2"));
166 
167  VisMF::Write(*(vec_zeta[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "zeta"));
168  VisMF::Write(*(vec_Zt_avg1[lev]), amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "Zt_avg1"));
169  }
170 
171 #ifdef REMORA_USE_PARTICLES
172  particleData.Checkpoint(checkpointname);
173 #endif
174 
175 #ifdef REMORA_USE_NETCDF
176  // Write bdy_data files
177  if ( ParallelDescriptor::IOProcessor() && (solverChoice.ic_bc_type == IC_BC_Type::Real) )
178  {
179 
180  // Vector dimensions
181  int num_time = bdy_data_xlo.size();
182  int num_var = bdy_data_xlo[0].size();
183 
184  // Open header file and write to it
185  std::ofstream bdy_h_file(amrex::MultiFabFileFullPrefix(0, checkpointname, "Level_", "bdy_H"));
186  bdy_h_file << std::setprecision(1) << std::fixed;
187  bdy_h_file << num_time << "\n";
188  bdy_h_file << num_var << "\n";
189  bdy_h_file << start_bdy_time << "\n";
190  bdy_h_file << bdy_time_interval << "\n";
191  bdy_h_file << bdy_width << "\n";
192  for (int ivar(0); ivar<num_var; ++ivar) {
193  bdy_h_file << bdy_data_xlo[0][ivar].box() << "\n";
194  bdy_h_file << bdy_data_xhi[0][ivar].box() << "\n";
195  bdy_h_file << bdy_data_ylo[0][ivar].box() << "\n";
196  bdy_h_file << bdy_data_yhi[0][ivar].box() << "\n";
197  }
198 
199  // Open data file and write to it
200  std::ofstream bdy_d_file(amrex::MultiFabFileFullPrefix(0, checkpointname, "Level_", "bdy_D"));
201  for (int itime(0); itime<num_time; ++itime) {
202  for (int ivar(0); ivar<num_var; ++ivar) {
203  bdy_data_xlo[itime][ivar].writeOn(bdy_d_file,0,1);
204  bdy_data_xhi[itime][ivar].writeOn(bdy_d_file,0,1);
205  bdy_data_ylo[itime][ivar].writeOn(bdy_d_file,0,1);
206  bdy_data_yhi[itime][ivar].writeOn(bdy_d_file,0,1);
207  }
208  }
209  }
210 #endif
211 }

◆ WriteGenericPlotfileHeaderWithBathymetry()

void REMORA::WriteGenericPlotfileHeaderWithBathymetry ( std::ostream &  HeaderFile,
int  nlevels,
const amrex::Vector< amrex::BoxArray > &  bArray,
const amrex::Vector< std::string > &  varnames,
amrex::Real  time,
const amrex::Vector< int > &  level_steps,
const std::string &  versionName,
const std::string &  levelPrefix,
const std::string &  mfPrefix 
) const
399 {
400  BL_ASSERT(nlevels <= bArray.size());
401  BL_ASSERT(nlevels <= ref_ratio.size()+1);
402  BL_ASSERT(nlevels <= level_steps.size());
403 
404  HeaderFile.precision(17);
405 
406  // ---- this is the generic plot file type name
407  HeaderFile << versionName << '\n';
408 
409  HeaderFile << varnames.size() << '\n';
410 
411  for (int ivar = 0; ivar < varnames.size(); ++ivar) {
412  HeaderFile << varnames[ivar] << "\n";
413  }
414  HeaderFile << AMREX_SPACEDIM << '\n';
415  HeaderFile << time << '\n';
416  HeaderFile << finest_level << '\n';
417  for (int i = 0; i < AMREX_SPACEDIM; ++i) {
418  HeaderFile << geom[0].ProbLo(i) << ' ';
419  }
420  HeaderFile << '\n';
421  for (int i = 0; i < AMREX_SPACEDIM; ++i) {
422  HeaderFile << geom[0].ProbHi(i) << ' ';
423  }
424  HeaderFile << '\n';
425  for (int i = 0; i < finest_level; ++i) {
426  HeaderFile << ref_ratio[i][0] << ' ';
427  }
428  HeaderFile << '\n';
429  for (int i = 0; i <= finest_level; ++i) {
430  HeaderFile << geom[i].Domain() << ' ';
431  }
432  HeaderFile << '\n';
433  for (int i = 0; i <= finest_level; ++i) {
434  HeaderFile << level_steps[i] << ' ';
435  }
436  HeaderFile << '\n';
437  for (int i = 0; i <= finest_level; ++i) {
438  for (int k = 0; k < AMREX_SPACEDIM; ++k) {
439  HeaderFile << geom[i].CellSize()[k] << ' ';
440  }
441  HeaderFile << '\n';
442  }
443  HeaderFile << (int) geom[0].Coord() << '\n';
444  HeaderFile << "0\n";
445 
446  for (int level = 0; level <= finest_level; ++level) {
447  HeaderFile << level << ' ' << bArray[level].size() << ' ' << time << '\n';
448  HeaderFile << level_steps[level] << '\n';
449 
450  const IntVect& domain_lo = geom[level].Domain().smallEnd();
451  for (int i = 0; i < bArray[level].size(); ++i)
452  {
453  // Need to shift because the RealBox ctor we call takes the
454  // physical location of index (0,0,0). This does not affect
455  // the usual cases where the domain index starts with 0.
456  const Box& b = shift(bArray[level][i], -domain_lo);
457  RealBox loc = RealBox(b, geom[level].CellSize(), geom[level].ProbLo());
458  for (int n = 0; n < AMREX_SPACEDIM; ++n) {
459  HeaderFile << loc.lo(n) << ' ' << loc.hi(n) << '\n';
460  }
461  }
462 
463  HeaderFile << MultiFabHeaderPath(level, levelPrefix, mfPrefix) << '\n';
464  }
465  HeaderFile << "1" << "\n";
466  HeaderFile << "3" << "\n";
467  HeaderFile << "amrexvec_nu_x" << "\n";
468  HeaderFile << "amrexvec_nu_y" << "\n";
469  HeaderFile << "amrexvec_nu_z" << "\n";
470  std::string mf_nodal_prefix = "Nu_nd";
471  for (int level = 0; level <= finest_level; ++level) {
472  HeaderFile << MultiFabHeaderPath(level, levelPrefix, mf_nodal_prefix) << '\n';
473  }
474 }
Coord
Definition: DataStruct.H:17

◆ writeJobInfo()

void REMORA::writeJobInfo ( const std::string &  dir) const
8 {
9  // job_info file with details about the run
10  std::ofstream jobInfoFile;
11  std::string FullPathJobInfoFile = dir;
12  FullPathJobInfoFile += "/job_info";
13  jobInfoFile.open(FullPathJobInfoFile.c_str(), std::ios::out);
14 
15  std::string PrettyLine = "==================================================="
16  "============================\n";
17  std::string OtherLine = "----------------------------------------------------"
18  "----------------------------\n";
19  std::string SkipSpace = " ";
20 
21  // job information
22  jobInfoFile << PrettyLine;
23  jobInfoFile << " REMORA Job Information\n";
24  jobInfoFile << PrettyLine;
25 
26  jobInfoFile << "inputs file: " << inputs_name << "\n\n";
27 
28  jobInfoFile << "number of MPI processes: "
29  << amrex::ParallelDescriptor::NProcs() << "\n";
30 #ifdef _OPENMP
31  jobInfoFile << "number of threads: " << omp_get_max_threads() << "\n";
32 #endif
33 
34  jobInfoFile << "\n";
35  jobInfoFile << "CPU time used since start of simulation (CPU-hours): "
36  << getCPUTime() / 3600.0;
37 
38  jobInfoFile << "\n\n";
39 
40  // plotfile information
41  jobInfoFile << PrettyLine;
42  jobInfoFile << " Plotfile Information\n";
43  jobInfoFile << PrettyLine;
44 
45  time_t now = time(0);
46 
47  // Convert now to tm struct for local timezone
48  tm* localtm = localtime(&now);
49  jobInfoFile << "output data / time: " << asctime(localtm);
50 
51  std::string currentDir = amrex::FileSystem::CurrentPath();
52  jobInfoFile << "output dir: " << currentDir << "\n";
53 
54  jobInfoFile << "\n\n";
55 
56  // build information
57  jobInfoFile << PrettyLine;
58  jobInfoFile << " Build Information\n";
59  jobInfoFile << PrettyLine;
60 
61  jobInfoFile << "build date: " << amrex::buildInfoGetBuildDate() << "\n";
62  jobInfoFile << "build machine: " << amrex::buildInfoGetBuildMachine() << "\n";
63  jobInfoFile << "build dir: " << amrex::buildInfoGetBuildDir() << "\n";
64  jobInfoFile << "AMReX dir: " << amrex::buildInfoGetAMReXDir() << "\n";
65 
66  jobInfoFile << "\n";
67 
68  jobInfoFile << "COMP: " << amrex::buildInfoGetComp() << "\n";
69  jobInfoFile << "COMP version: " << amrex::buildInfoGetCompVersion() << "\n";
70 
71  jobInfoFile << "\n";
72 
73  for (int n = 1; n <= amrex::buildInfoGetNumModules(); n++) {
74  jobInfoFile << amrex::buildInfoGetModuleName(n) << ": "
75  << amrex::buildInfoGetModuleVal(n) << "\n";
76  }
77 
78  jobInfoFile << "\n";
79 
80  const char* githash1 = amrex::buildInfoGetGitHash(1);
81  const char* githash2 = amrex::buildInfoGetGitHash(2);
82  if (strlen(githash1) > 0) {
83  jobInfoFile << "REMORA git hash: " << githash1 << "\n";
84  }
85  if (strlen(githash2) > 0) {
86  jobInfoFile << "AMReX git hash: " << githash2 << "\n";
87  }
88 
89  const char* buildgithash = amrex::buildInfoGetBuildGitHash();
90  const char* buildgitname = amrex::buildInfoGetBuildGitName();
91  if (strlen(buildgithash) > 0) {
92  jobInfoFile << buildgitname << " git hash: " << buildgithash << "\n";
93  }
94 
95  jobInfoFile << "\n\n";
96 
97  // grid information
98  jobInfoFile << PrettyLine;
99  jobInfoFile << " Grid Information\n";
100  jobInfoFile << PrettyLine;
101 
102  int f_lev = finest_level;
103 
104  for (int i = 0; i <= f_lev; i++) {
105  jobInfoFile << " level: " << i << "\n";
106  jobInfoFile << " number of boxes = " << grids[i].size() << "\n";
107  jobInfoFile << " maximum zones = ";
108  for (int n = 0; n < AMREX_SPACEDIM; n++) {
109  jobInfoFile << geom[i].Domain().length(n) << " ";
110  }
111  jobInfoFile << "\n\n";
112  }
113 
114  jobInfoFile << " Boundary conditions\n";
115 
116  jobInfoFile << " -x: " << domain_bc_type[0] << "\n";
117  jobInfoFile << " +x: " << domain_bc_type[3] << "\n";
118  jobInfoFile << " -y: " << domain_bc_type[1] << "\n";
119  jobInfoFile << " +y: " << domain_bc_type[4] << "\n";
120  jobInfoFile << " -z: " << domain_bc_type[2] << "\n";
121  jobInfoFile << " +z: " << domain_bc_type[5] << "\n";
122 
123  jobInfoFile << "\n\n";
124 
125  // runtime parameters
126  jobInfoFile << PrettyLine;
127  jobInfoFile << " Inputs File Parameters\n";
128  jobInfoFile << PrettyLine;
129 
130  amrex::ParmParse::dumpTable(jobInfoFile, true);
131  jobInfoFile.close();
132 }
amrex::Real getCPUTime() const
Definition: REMORA.H:940
std::string inputs_name
Definition: main.cpp:9
Here is the call graph for this function:

◆ WriteMultiLevelPlotfileWithBathymetry()

void REMORA::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< std::string > &  varnames,
amrex::Real  time,
const amrex::Vector< int > &  level_steps,
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
315 {
316  BL_PROFILE("WriteMultiLevelPlotfileWithBathymetry()");
317 
318  BL_ASSERT(nlevels <= mf.size());
319  BL_ASSERT(nlevels <= ref_ratio.size()+1);
320  BL_ASSERT(nlevels <= level_steps.size());
321  BL_ASSERT(mf[0]->nComp() == varnames.size());
322 
323  bool callBarrier(false);
324  PreBuildDirectorHierarchy(plotfilename, levelPrefix, nlevels, callBarrier);
325  if (!extra_dirs.empty()) {
326  for (const auto& d : extra_dirs) {
327  const std::string ed = plotfilename+"/"+d;
328  PreBuildDirectorHierarchy(ed, levelPrefix, nlevels, callBarrier);
329  }
330  }
331  ParallelDescriptor::Barrier();
332 
333  if (ParallelDescriptor::MyProc() == ParallelDescriptor::NProcs()-1) {
334  Vector<BoxArray> boxArrays(nlevels);
335  for(int level(0); level < boxArrays.size(); ++level) {
336  boxArrays[level] = mf[level]->boxArray();
337  }
338 
339  auto f = [=]() {
340  VisMF::IO_Buffer io_buffer(VisMF::IO_Buffer_Size);
341  std::string HeaderFileName(plotfilename + "/Header");
342  std::ofstream HeaderFile;
343  HeaderFile.rdbuf()->pubsetbuf(io_buffer.dataPtr(), io_buffer.size());
344  HeaderFile.open(HeaderFileName.c_str(), std::ofstream::out |
345  std::ofstream::trunc |
346  std::ofstream::binary);
347  if( ! HeaderFile.good()) FileOpenFailed(HeaderFileName);
348  WriteGenericPlotfileHeaderWithBathymetry(HeaderFile, nlevels, boxArrays, varnames,
349  time, level_steps, versionName,
350  levelPrefix, mfPrefix);
351  };
352 
353  if (AsyncOut::UseAsyncOut()) {
354  AsyncOut::Submit(std::move(f));
355  } else {
356  f();
357  }
358  }
359 
360  std::string mf_nodal_prefix = "Nu_nd";
361  for (int level = 0; level <= finest_level; ++level)
362  {
363  if (AsyncOut::UseAsyncOut()) {
364  VisMF::AsyncWrite(*mf[level],
365  MultiFabFileFullPrefix(level, plotfilename, levelPrefix, mfPrefix),
366  true);
367  VisMF::AsyncWrite(*mf_nd[level],
368  MultiFabFileFullPrefix(level, plotfilename, levelPrefix, mf_nodal_prefix),
369  true);
370  } else {
371  const MultiFab* data;
372  std::unique_ptr<MultiFab> mf_tmp;
373  if (mf[level]->nGrowVect() != 0) {
374  mf_tmp = std::make_unique<MultiFab>(mf[level]->boxArray(),
375  mf[level]->DistributionMap(),
376  mf[level]->nComp(), 0, MFInfo(),
377  mf[level]->Factory());
378  MultiFab::Copy(*mf_tmp, *mf[level], 0, 0, mf[level]->nComp(), 0);
379  data = mf_tmp.get();
380  } else {
381  data = mf[level];
382  }
383  VisMF::Write(*data , MultiFabFileFullPrefix(level, plotfilename, levelPrefix, mfPrefix));
384  VisMF::Write(*mf_nd[level], MultiFabFileFullPrefix(level, plotfilename, levelPrefix, mf_nodal_prefix));
385  }
386  }
387 }
void WriteGenericPlotfileHeaderWithBathymetry(std::ostream &HeaderFile, int nlevels, const amrex::Vector< amrex::BoxArray > &bArray, const amrex::Vector< std::string > &varnames, amrex::Real time, const amrex::Vector< int > &level_steps, const std::string &versionName, const std::string &levelPrefix, const std::string &mfPrefix) const
Definition: Plotfile.cpp:390

◆ WritePlotFile()

void REMORA::WritePlotFile ( int  which,
amrex::Vector< std::string >  plot_var_names 
)

write plotfile to disk

100 {
101  const Vector<std::string> varnames = PlotFileVarNames(plot_var_names);
102  const int ncomp_mf = varnames.size();
103  const auto ngrow_vars = IntVect(NGROW-1,NGROW-1,0);
104 
105  // We fillpatch here because some of the derived quantities require derivatives
106  // which require ghost cells to be filled
107  for (int lev = 0; lev <= finest_level; ++lev) {
108  FillPatch(lev, t_new[lev], *cons_new[lev], cons_new, BdyVars::t);
109  FillPatch(lev, t_new[lev], *xvel_new[lev], xvel_new, BdyVars::u);
110  FillPatch(lev, t_new[lev], *yvel_new[lev], yvel_new, BdyVars::v);
111  FillPatch(lev, t_new[lev], *zvel_new[lev], zvel_new, BdyVars::null);
112  }
113 
114  if (ncomp_mf == 0)
115  return;
116 
117  Vector<MultiFab> mf(finest_level+1);
118  for (int lev = 0; lev <= finest_level; ++lev) {
119  mf[lev].define(grids[lev], dmap[lev], ncomp_mf, ngrow_vars);
120  }
121 
122  Vector<MultiFab> mf_nd(finest_level+1);
123  for (int lev = 0; lev <= finest_level; ++lev) {
124  BoxArray nodal_grids(grids[lev]); nodal_grids.surroundingNodes();
125  mf_nd[lev].define(nodal_grids, dmap[lev], AMREX_SPACEDIM, 0);
126  mf_nd[lev].setVal(0.);
127  }
128 
129  for (int lev = 0; lev <= finest_level; ++lev) {
130  int mf_comp = 0;
131 
132  // First, copy any of the conserved state variables into the output plotfile
133  AMREX_ALWAYS_ASSERT(cons_names.size() == NCONS);
134  for (int i = 0; i < NCONS; ++i) {
135  if (containerHasElement(plot_var_names, cons_names[i])) {
136  MultiFab::Copy(mf[lev],*cons_new[lev],i,mf_comp,1,ngrow_vars);
137  mf_comp++;
138  }
139  }
140 
141  // Next, check for velocities and output none or all
142  if (containerHasElement(plot_var_names, "x_velocity") ||
143  containerHasElement(plot_var_names, "y_velocity") ||
144  containerHasElement(plot_var_names, "z_velocity")) {
146  Print()<<"We now average the face-based velocity components onto cell centers for plotting "<<std::endl;
147  }
148  average_face_to_cellcenter(mf[lev],mf_comp,
149  Array<const MultiFab*,3>{xvel_new[lev],yvel_new[lev],zvel_new[lev]});
150  mf_comp += AMREX_SPACEDIM;
151  }
152 
153  // Fill cell-centered location
154  Real dx = Geom()[lev].CellSizeArray()[0];
155  Real dy = Geom()[lev].CellSizeArray()[1];
156 
157  // Next, check for location names -- if we write one we write all
158  if (containerHasElement(plot_var_names, "x_cc") ||
159  containerHasElement(plot_var_names, "y_cc") ||
160  containerHasElement(plot_var_names, "z_cc"))
161  {
162  MultiFab dmf(mf[lev], make_alias, mf_comp, AMREX_SPACEDIM);
163  for (MFIter mfi(dmf, TilingIfNotGPU()); mfi.isValid(); ++mfi) {
164  const Box& bx = mfi.tilebox();
165  const Array4<Real> loc_arr = dmf.array(mfi);
166  const Array4<Real const> zp_arr = vec_z_phys_nd[lev]->const_array(mfi);
167 
168  ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) {
169  loc_arr(i,j,k,0) = (i+0.5) * dx;
170  loc_arr(i,j,k,1) = (j+0.5) * dy;
171  loc_arr(i,j,k,2) = 0.125_rt * (zp_arr(i,j ,k ) + zp_arr(i+1,j ,k ) +
172  zp_arr(i,j+1,k ) + zp_arr(i+1,j+1,k ) +
173  zp_arr(i,j ,k+1) + zp_arr(i+1,j ,k+1) +
174  zp_arr(i,j+1,k+1) + zp_arr(i+1,j+1,k+1) );
175  });
176  } // mfi
177  mf_comp += AMREX_SPACEDIM;
178  } // if containerHasElement
179 
180 #ifdef REMORA_USE_PARTICLES
181  if (containerHasElement(plot_var_names, "tracer_particle_count"))
182  {
183  MultiFab temp_dat(mf[lev].boxArray(), mf[lev].DistributionMap(), 1, 0);
184  temp_dat.setVal(0);
185  particleData.tracer_particles->Redistribute();
186  particleData.tracer_particles->Increment(temp_dat, lev);
187  MultiFab::Copy(mf[lev], temp_dat, 0, mf_comp, 1, 0);
188  mf_comp += 1;
189  }
190 #endif
191 
192  MultiFab::Copy(mf_nd[lev],*vec_z_phys_nd[lev],0,2,1,0);
193  Real dz = Geom()[lev].CellSizeArray()[2];
194  for (MFIter mfi(mf_nd[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi)
195  {
196  const Box& bx = mfi.tilebox();
197  Array4<Real> mf_arr = mf_nd[lev].array(mfi);
198  ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) {
199  mf_arr(i,j,k,2) -= k * dz;
200  });
201  } // mfi
202 
203  } // lev
204 
205  std::string plotfilename;
206  if (which == 1)
207  plotfilename = Concatenate(plot_file_1, istep[0], 5);
208  else if (which == 2)
209  plotfilename = Concatenate(plot_file_2, istep[0], 5);
210 
211  if (finest_level == 0)
212  {
214  amrex::Print() << "Writing plotfile " << plotfilename << "\n";
215  WriteMultiLevelPlotfileWithBathymetry(plotfilename, finest_level+1,
216  GetVecOfConstPtrs(mf),
217  GetVecOfConstPtrs(mf_nd),
218  varnames,
219  t_new[0], istep);
220  writeJobInfo(plotfilename);
221 
222 #ifdef REMORA_USE_PARTICLES
223  particleData.Checkpoint(plotfilename);
224 #endif
225 
226 #ifdef REMORA_USE_HDF5
227  } else if (plotfile_type == PlotfileType::hdf5) {
228  amrex::Print() << "Writing plotfile " << plotfilename+"d01.h5" << "\n";
229  WriteMultiLevelPlotfileHDF5(plotfilename, finest_level+1,
230  GetVecOfConstPtrs(mf),
231  varnames,
232  Geom(), t_new[0], istep, refRatio());
233 #endif
234 #ifdef REMORA_USE_NETCDF
235  } else if (plotfile_type == PlotfileType::netcdf) {
236  // int lev = 0;
237  // int nc_which = 0;
238  // writeNCPlotFile(lev, nc_which, plotfilename, GetVecOfConstPtrs(mf), varnames, istep, t_new[0]);
239  // total_plot_file_step_1 += 1;
240 #endif
241  } else {
242  amrex::Abort("User specified unknown plot_filetype");
243  }
244 
245  } else { // multilevel
246 
247  Vector<IntVect> r2(finest_level);
248  Vector<Geometry> g2(finest_level+1);
249  Vector<MultiFab> mf2(finest_level+1);
250 
251  mf2[0].define(grids[0], dmap[0], ncomp_mf, 0);
252 
253  // Copy level 0 as is
254  MultiFab::Copy(mf2[0],mf[0],0,0,mf[0].nComp(),0);
255 
256  // Define a new multi-level array of Geometry's so that we pass the new "domain" at lev > 0
257  Array<int,AMREX_SPACEDIM> periodicity =
258  {Geom()[0].isPeriodic(0),Geom()[0].isPeriodic(1),Geom()[0].isPeriodic(2)};
259  g2[0].define(Geom()[0].Domain(),&(Geom()[0].ProbDomain()),0,periodicity.data());
260 
262  r2[0] = IntVect(1,1,ref_ratio[0][0]);
263  for (int lev = 1; lev <= finest_level; ++lev) {
264  if (lev > 1) {
265  r2[lev-1][0] = 1;
266  r2[lev-1][1] = 1;
267  r2[lev-1][2] = r2[lev-2][2] * ref_ratio[lev-1][0];
268  }
269 
270  mf2[lev].define(refine(grids[lev],r2[lev-1]), dmap[lev], ncomp_mf, 0);
271 
272  // Set the new problem domain
273  Box d2(Geom()[lev].Domain());
274  d2.refine(r2[lev-1]);
275 
276  g2[lev].define(d2,&(Geom()[lev].ProbDomain()),0,periodicity.data());
277  }
278 
279  // Do piecewise interpolation of mf into mf2
280  for (int lev = 1; lev <= finest_level; ++lev) {
281  for (MFIter mfi(mf2[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi) {
282  const Box& bx = mfi.tilebox();
283  pcinterp_interp(bx,mf2[lev].array(mfi), 0, mf[lev].nComp(), mf[lev].const_array(mfi),0,r2[lev-1]);
284  }
285  }
286 
287  // Define an effective ref_ratio which is isotropic to be passed into WriteMultiLevelPlotfile
288  Vector<IntVect> rr(finest_level);
289  for (int lev = 0; lev < finest_level; ++lev) {
290  rr[lev] = IntVect(ref_ratio[lev][0],ref_ratio[lev][1],ref_ratio[lev][0]);
291  }
292 
293  WriteMultiLevelPlotfile(plotfilename, finest_level+1, GetVecOfConstPtrs(mf2), varnames,
294  g2, t_new[0], istep, rr);
295  writeJobInfo(plotfilename);
296 
297 #ifdef REMORA_USE_PARTICLES
298  particleData.Checkpoint(plotfilename);
299 #endif
300  }
301  } // end multi-level
302 }
void writeJobInfo(const std::string &dir) const
Definition: writeJobInfo.cpp:7
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< std::string > &varnames, amrex::Real time, const amrex::Vector< int > &level_steps, 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
Definition: Plotfile.cpp:305
amrex::Vector< std::string > PlotFileVarNames(amrex::Vector< std::string > plot_var_names) const
Definition: Plotfile.cpp:87
Here is the call graph for this function:

Member Data Documentation

◆ advflux_reg

amrex::Vector<amrex::YAFluxRegister*> REMORA::advflux_reg
private

Referenced by getAdvFluxReg().

◆ bndry_output_planes_interval

int REMORA::bndry_output_planes_interval
staticprivate

◆ bndry_output_planes_per

amrex::Real REMORA::bndry_output_planes_per
staticprivate

◆ bndry_output_planes_start_time

amrex::Real REMORA::bndry_output_planes_start_time
staticprivate

◆ boxes_at_level

amrex::Vector<amrex::Vector<amrex::Box> > REMORA::boxes_at_level
private

◆ cfl

amrex::Real REMORA::cfl = 0.8
staticprivate

◆ change_max

amrex::Real REMORA::change_max = 1.1
staticprivate

◆ check_file

std::string REMORA::check_file {"chk"}
private

◆ check_int

int REMORA::check_int = -1
private

◆ column_file_name

std::string REMORA::column_file_name
staticprivate

◆ column_interval

int REMORA::column_interval
staticprivate

◆ column_loc_x

amrex::Real REMORA::column_loc_x
staticprivate

◆ column_loc_y

amrex::Real REMORA::column_loc_y
staticprivate

◆ column_per

amrex::Real REMORA::column_per
staticprivate

◆ cons_names

const amrex::Vector<std::string> REMORA::cons_names {"temp", "salt", "scalar"}
private

◆ cons_new

amrex::Vector<amrex::MultiFab*> REMORA::cons_new

◆ cons_old

amrex::Vector<amrex::MultiFab*> REMORA::cons_old

◆ d_havg_density

amrex::Gpu::DeviceVector<amrex::Real> REMORA::d_havg_density
private

◆ d_havg_pressure

amrex::Gpu::DeviceVector<amrex::Real> REMORA::d_havg_pressure
private

◆ d_havg_temperature

amrex::Gpu::DeviceVector<amrex::Real> REMORA::d_havg_temperature
private

◆ datalog

amrex::Vector<std::unique_ptr<std::fstream> > REMORA::datalog
private

◆ datalogname

amrex::Vector<std::string> REMORA::datalogname
private

Referenced by DataLogName().

◆ derived_names

const amrex::Vector<std::string> REMORA::derived_names {"dpdx", "dpdy"}
private

◆ do_substep

int REMORA::do_substep
private

◆ domain_bc_type

amrex::Array<std::string,2*AMREX_SPACEDIM> REMORA::domain_bc_type
private

Referenced by writeJobInfo().

◆ domain_bcs_type

amrex::Vector<amrex::BCRec> REMORA::domain_bcs_type
private

◆ domain_bcs_type_d

amrex::Gpu::DeviceVector<amrex::BCRec> REMORA::domain_bcs_type_d
private

◆ dt

amrex::Vector<amrex::Real> REMORA::dt
private

◆ fine_mask

amrex::MultiFab REMORA::fine_mask
private

◆ fixed_dt

amrex::Real REMORA::fixed_dt = -1.0
staticprivate

◆ fixed_fast_dt

amrex::Real REMORA::fixed_fast_dt = -1.0
staticprivate

◆ fixed_ndtfast_ratio

int REMORA::fixed_ndtfast_ratio = 0
staticprivate

◆ h_havg_density

amrex::Vector<amrex::Real> REMORA::h_havg_density
private

◆ h_havg_pressure

amrex::Vector<amrex::Real> REMORA::h_havg_pressure
private

◆ h_havg_temperature

amrex::Vector<amrex::Real> REMORA::h_havg_temperature
private

◆ init_shrink

amrex::Real REMORA::init_shrink = 1.0
staticprivate

◆ input_bndry_planes

int REMORA::input_bndry_planes
staticprivate

◆ input_sounding_file

std::string REMORA::input_sounding_file
staticprivate

◆ istep

amrex::Vector<int> REMORA::istep
private

◆ last_check_file_step

int REMORA::last_check_file_step
private

◆ last_plot_file_step_1

int REMORA::last_plot_file_step_1
private

◆ last_plot_file_step_2

int REMORA::last_plot_file_step_2
private

◆ m_bc_extdir_vals

amrex::Array<amrex::Array<amrex::Real, AMREX_SPACEDIM*2>,AMREX_SPACEDIM+NCONS> REMORA::m_bc_extdir_vals
private

◆ mapfac_m

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::mapfac_m
private

◆ mapfac_u

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::mapfac_u
private

◆ mapfac_v

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::mapfac_v
private

◆ max_step

int REMORA::max_step = std::numeric_limits<int>::max()
private

◆ nc_bdry_file

std::string REMORA::nc_bdry_file
staticprivate

◆ nc_grid_file

amrex::Vector<amrex::Vector<std::string> > REMORA::nc_grid_file
staticprivate

◆ nc_init_file

amrex::Vector<amrex::Vector<std::string> > REMORA::nc_init_file
staticprivate

◆ nfast

int REMORA::nfast
private

◆ nsubsteps

amrex::Vector<int> REMORA::nsubsteps
private

◆ num_boxes_at_level

amrex::Vector<int> REMORA::num_boxes_at_level
private

◆ num_files_at_level

amrex::Vector<int> REMORA::num_files_at_level
private

◆ output_1d_column

int REMORA::output_1d_column
staticprivate

◆ output_bndry_planes

int REMORA::output_bndry_planes
staticprivate

◆ phys_bc_type

amrex::GpuArray<REMORA_BC, AMREX_SPACEDIM*2> REMORA::phys_bc_type
private

◆ physbcs

amrex::Vector<std::unique_ptr<REMORAPhysBCFunct> > REMORA::physbcs
private

◆ plot_file_1

std::string REMORA::plot_file_1 {"plt_1_"}
private

◆ plot_file_2

std::string REMORA::plot_file_2 {"plt_2_"}
private

◆ plot_file_on_restart

int REMORA::plot_file_on_restart = 1
private

◆ plot_int_1

int REMORA::plot_int_1 = -1
private

◆ plot_int_2

int REMORA::plot_int_2 = -1
private

◆ plot_var_names_1

amrex::Vector<std::string> REMORA::plot_var_names_1
private

◆ plot_var_names_2

amrex::Vector<std::string> REMORA::plot_var_names_2
private

◆ plotfile_type

PlotfileType REMORA::plotfile_type = PlotfileType::amrex
staticprivate

◆ pp_prefix

std::string REMORA::pp_prefix {"remora"}

◆ previousCPUTimeUsed

amrex::Real REMORA::previousCPUTimeUsed = 0.0
staticprivate

Referenced by getCPUTime().

◆ ref_tags

Vector< AMRErrorTag > REMORA::ref_tags
staticprivate

◆ regrid_int

int REMORA::regrid_int = 2
private

◆ restart_chkfile

std::string REMORA::restart_chkfile = ""
private

◆ solverChoice

SolverChoice REMORA::solverChoice
staticprivate

◆ sst

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::sst
private

◆ startCPUTime

amrex::Real REMORA::startCPUTime = 0.0
staticprivate

Referenced by getCPUTime().

◆ stop_time

amrex::Real REMORA::stop_time = std::numeric_limits<amrex::Real>::max()
private

◆ sum_interval

int REMORA::sum_interval = -1
staticprivate

◆ sum_per

amrex::Real REMORA::sum_per = -1.0
staticprivate

◆ t_new

amrex::Vector<amrex::Real> REMORA::t_new
private

◆ t_old

amrex::Vector<amrex::Real> REMORA::t_old
private

◆ use_tracer_particles

bool REMORA::use_tracer_particles
staticprivate

◆ vec_Akt

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_Akt

Vertical diffusion coefficient (3D), set in .in file

◆ vec_Akv

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_Akv

Vertical viscosity coefficient (3D), set in .in file

◆ vec_bustr

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_bustr

Bottom stress in the u direction

◆ vec_bvstr

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_bvstr

Bottom stress in the v direction

◆ vec_diff2

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_diff2

Harmonic diffusivity for temperature / salinity

◆ vec_DU_avg1

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_DU_avg1

time average of barotropic x velocity flux (2D)

◆ vec_DU_avg2

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_DU_avg2

correct time average of barotropic x velocity flux for coupling (2D)

◆ vec_DV_avg1

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_DV_avg1

time average of barotropic y velocity flux

◆ vec_DV_avg2

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_DV_avg2

correct time average of barotropic y velocity flux for coupling (2D)

◆ vec_fcor

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_fcor

coriolis factor (2D)

◆ vec_hOfTheConfusingName

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_hOfTheConfusingName

Bathymetry data (2D, positive valued, h in ROMS)

◆ vec_Huon

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_Huon

u-volume flux (3D)

◆ vec_Hvom

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_Hvom

v-volume flux (3D)

◆ vec_Hz

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_Hz

Width of cells in the vertical (z-) direction (3D, Hz in ROMS)

◆ vec_pm

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_pm

map factor (2D)

◆ vec_pn

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_pn

map factor (2D)

◆ vec_rdrag

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_rdrag

Linear drag coefficient [m/s], defined at rho points

◆ vec_rhoA

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_rhoA

◆ vec_rhoS

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_rhoS

◆ vec_ru

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_ru

u velocity RHS (3D, includes horizontal and vertical advection)

◆ vec_rubar

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_rubar

barotropic x velocity for the RHS (2D)

◆ vec_rufrc

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_rufrc

u velocity RHS, integrated, including advection and bottom/surface stresses (2D)

◆ vec_rv

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_rv

v velocity RHS (3D, includes horizontal and vertical advection)

◆ vec_rvbar

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_rvbar

barotropic y velocity for the RHS (2D)

◆ vec_rvfrc

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_rvfrc

v velocity RHS, integrated, including advection and bottom/surface stresses (2D)

◆ vec_rzeta

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_rzeta

free surface height for the RHS (2D)

◆ vec_s_r

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_s_r

Scaled vertical coordinate (range [0,1]) that transforms to z, defined at rho points (cell centers)

◆ vec_sstore

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_sstore

saltstore, tempstore, etc

◆ vec_sustr

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_sustr

Surface stress in the u direction

◆ vec_svstr

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_svstr

Surface stress in the v direction

◆ vec_ubar

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_ubar

barotropic x velocity (2D)

◆ vec_vbar

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_vbar

barotropic y velocity (2D)

◆ vec_visc2_p

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_visc2_p

Harmonic viscosity devined on the psi points (corners of horizontal grid cells)

◆ vec_visc2_r

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_visc2_r

Harmonic viscosity devined on the rho points (centers)

◆ vec_visc3d_r

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_visc3d_r

◆ vec_weight1

amrex::Vector<amrex::Real> REMORA::vec_weight1

◆ vec_weight2

amrex::Vector<amrex::Real> REMORA::vec_weight2

◆ vec_x_r

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_x_r

x coordinates at rho points (cell centers)

◆ vec_y_r

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_y_r

y coordinates at rho points (cell centers)

◆ vec_z_phys_nd

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_z_phys_nd

z coordinates at psi points (cell nodes)

◆ vec_z_r

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_z_r

z coordinates at rho points (cell centers)

◆ vec_z_w

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_z_w

z coordinates at w points (faces between z-cells)

◆ vec_zeta

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_zeta

free surface height (2D)

◆ vec_Zt_avg1

amrex::Vector<std::unique_ptr<amrex::MultiFab> > REMORA::vec_Zt_avg1

Average of the free surface, zeta (2D)

◆ verbose

int REMORA::verbose = 0
staticprivate

◆ xvel_new

amrex::Vector<amrex::MultiFab*> REMORA::xvel_new

◆ xvel_old

amrex::Vector<amrex::MultiFab*> REMORA::xvel_old

◆ yvel_new

amrex::Vector<amrex::MultiFab*> REMORA::yvel_new

◆ yvel_old

amrex::Vector<amrex::MultiFab*> REMORA::yvel_old

◆ zvel_new

amrex::Vector<amrex::MultiFab*> REMORA::zvel_new

◆ zvel_old

amrex::Vector<amrex::MultiFab*> REMORA::zvel_old

The documentation for this class was generated from the following files: