ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
MOSTAverage Class Reference

#include <ERF_MOSTAverage.H>

Collaboration diagram for MOSTAverage:

Public Member Functions

 MOSTAverage (amrex::Vector< amrex::Geometry > geom, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars_old, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Theta_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qv_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qr_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &z_phys_nd)
 
 ~MOSTAverage ()
 
 MOSTAverage (MOSTAverage &&) noexcept=default
 
MOSTAverageoperator= (MOSTAverage &&other) noexcept=delete
 
 MOSTAverage (const MOSTAverage &other)=delete
 
MOSTAverageoperator= (const MOSTAverage &other)=delete
 
void update_field_ptrs (int lev, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars_old, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Theta_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qv_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qr_prim)
 
void set_rotated_fields (int lev)
 
void set_plane_normalization ()
 
void set_region_normalization ()
 
void set_k_indices_N ()
 
void set_k_indices_T ()
 
void set_norm_indices_T ()
 
void set_z_positions_T ()
 
void set_norm_positions_T ()
 
void compute_averages (int lev)
 
void compute_plane_averages (int lev)
 
void compute_region_averages (int lev)
 
void write_k_indices (int lev)
 
void write_norm_indices (int lev)
 
void write_xz_positions (int lev, int j)
 
void write_averages (int lev)
 
const amrex::MultiFab * get_average (int lev, int comp) const
 
amrex::Real get_zref () const
 

Static Public Member Functions

AMREX_GPU_HOST_DEVICE static AMREX_INLINE void trilinear_interp_T (const amrex::Real &xp, const amrex::Real &yp, const amrex::Real &zp, amrex::Real *interp_vals, amrex::Array4< amrex::Real const > const &interp_array, amrex::Array4< amrex::Real const > const &z_arr, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &plo, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dxi, const int interp_comp)
 

Protected Attributes

const amrex::Vector< amrex::Geometry > m_geom
 
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_fields
 
amrex::Vector< amrex::MultiFab * > m_z_phys_nd
 
int m_nvar {6}
 
int m_navg {6}
 
int m_maxlev {0}
 
int m_policy {0}
 
bool m_rotate {false}
 
amrex::Real m_zref {10.0}
 
std::string m_pp_prefix {"erf"}
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_x_pos
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_y_pos
 
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_z_pos
 
amrex::Vector< std::unique_ptr< amrex::iMultiFab > > m_i_indx
 
amrex::Vector< std::unique_ptr< amrex::iMultiFab > > m_j_indx
 
amrex::Vector< std::unique_ptr< amrex::iMultiFab > > m_k_indx
 
amrex::Vector< amrex::Vector< std::unique_ptr< amrex::MultiFab > > > m_averages
 
amrex::Vector< amrex::Vector< std::unique_ptr< amrex::MultiFab > > > m_rot_fields
 
amrex::Vector< amrex::Vector< int > > m_ncell_plane
 
amrex::Vector< amrex::Vector< amrex::Real > > m_plane_average
 
int m_radius {0}
 
int m_ncell_region {1}
 
amrex::Vector< int > m_k_in
 
bool m_interp {false}
 
bool m_norm_vec {false}
 
bool m_t_avg {false}
 
amrex::Vector< int > m_t_init
 
amrex::Real m_time_window {1.0e-16}
 
amrex::Real m_fact_new
 
amrex::Real m_fact_old
 
bool include_subgrid_vel = false
 
amrex::Vector< amrex::Real > m_Vsg
 

Constructor & Destructor Documentation

◆ MOSTAverage() [1/3]

MOSTAverage::MOSTAverage ( amrex::Vector< amrex::Geometry >  geom,
amrex::Vector< amrex::Vector< amrex::MultiFab >> &  vars_old,
amrex::Vector< std::unique_ptr< amrex::MultiFab >> &  Theta_prim,
amrex::Vector< std::unique_ptr< amrex::MultiFab >> &  Qv_prim,
amrex::Vector< std::unique_ptr< amrex::MultiFab >> &  Qr_prim,
amrex::Vector< std::unique_ptr< amrex::MultiFab >> &  z_phys_nd 
)
explicit

◆ ~MOSTAverage()

MOSTAverage::~MOSTAverage ( )
inline
23  {}

◆ MOSTAverage() [2/3]

MOSTAverage::MOSTAverage ( MOSTAverage &&  )
defaultnoexcept

◆ MOSTAverage() [3/3]

MOSTAverage::MOSTAverage ( const MOSTAverage other)
delete

Member Function Documentation

◆ compute_averages()

void MOSTAverage::compute_averages ( int  lev)

Function to call the type of average computation.

Parameters
[in]levCurrent level
665 {
666  if (m_rotate) set_rotated_fields(lev);
667 
668  switch(m_policy) {
669  case 0: // Standard plane average
671  break;
672  case 1: // Local region/point
674  break;
675  default:
676  AMREX_ASSERT_WITH_MESSAGE(false, "Unknown policy for MOSTAverage!");
677  }
678 
679  // We have initialized the averages
680  if (m_t_avg) m_t_init[lev] = 1;
681 }
bool m_t_avg
Definition: ERF_MOSTAverage.H:209
int m_policy
Definition: ERF_MOSTAverage.H:178
void set_rotated_fields(int lev)
Definition: ERF_MOSTAverage.cpp:247
amrex::Vector< int > m_t_init
Definition: ERF_MOSTAverage.H:210
bool m_rotate
Definition: ERF_MOSTAverage.H:179
void compute_region_averages(int lev)
Definition: ERF_MOSTAverage.cpp:975
void compute_plane_averages(int lev)
Definition: ERF_MOSTAverage.cpp:690
Here is the call graph for this function:

◆ compute_plane_averages()

void MOSTAverage::compute_plane_averages ( int  lev)

Function to compute average over a plane.

Parameters
[in]levCurrent level
691 {
692  // Peel back the level
693  auto& fields = m_fields[lev];
694  auto& rot_fields = m_rot_fields[lev];
695  auto& averages = m_averages[lev];
696  const auto & geom = m_geom[lev];
697 
698  auto& z_phys = m_z_phys_nd[lev];
699  auto& x_pos = m_x_pos[lev];
700  auto& y_pos = m_y_pos[lev];
701  auto& z_pos = m_z_pos[lev];
702 
703  auto& i_indx = m_i_indx[lev];
704  auto& j_indx = m_j_indx[lev];
705  auto& k_indx = m_k_indx[lev];
706 
707  auto& ncell_plane = m_ncell_plane[lev];
708  auto& plane_average = m_plane_average[lev];
709 
710  // Set factors for time averaging
711  Real d_fact_new, d_fact_old;
712  if (m_t_avg && m_t_init[lev]) {
713  d_fact_new = m_fact_new;
714  d_fact_old = m_fact_old;
715  } else {
716  d_fact_new = 1.0;
717  d_fact_old = 0.0;
718  }
719 
720  // GPU array to accumulate averages into
721  Gpu::DeviceVector<Real> pavg(plane_average.size(), 0.0);
722  Real* plane_avg = pavg.data();
723 
724  // Vectors for normalization and buffer storage
725  Vector<Real> denom(plane_average.size(),0.0);
726  Vector<Real> val_old(plane_average.size(),0.0);
727 
728  //
729  //----------------------------------------------------------
730  // Averages over all the fields
731  //----------------------------------------------------------
732  //
733  Box domain = geom.Domain();
734 
735  Array<int,AMREX_SPACEDIM> is_per = {0,0,0};
736  for (int idim(0); idim < AMREX_SPACEDIM-1; ++idim) {
737  if (geom.isPeriodic(idim)) is_per[idim] = 1;
738  }
739 
740  // Averages for U,V,T,Qv (not Qr or W)
741  for (int imf(0); imf < 4; ++imf) {
742 
743  // Continue if no valid Qv pointer
744  if (!fields[imf]) continue;
745 
746  denom[imf] = 1.0 / (Real)ncell_plane[imf];
747  val_old[imf] = plane_average[imf]*d_fact_old;
748 
749 #ifdef _OPENMP
750 #pragma omp parallel if (Gpu::notInLaunchRegion())
751 #endif
752  for (MFIter mfi(*fields[imf], TileNoZ()); mfi.isValid(); ++mfi) {
753  Box vbx = mfi.validbox(); // This is the grid (not tile)
754  Box pbx = mfi.tilebox(); // This is the tile (not grid)
755  pbx.setSmall(2,0); pbx.setBig(2,0);
756 
757  // Avoid double counting nodal data by changing the high end when we are
758  // at the high side of the grid (not just of the tile)
759  IndexType ixt = averages[imf]->boxArray().ixType();
760  for (int idim(0); idim < AMREX_SPACEDIM-1; ++idim) {
761  if ( ixt.nodeCentered(idim) && (pbx.bigEnd(idim) == vbx.bigEnd(idim)) ) {
762  int dom_hi = domain.bigEnd(idim)+1;
763  if (pbx.bigEnd(idim) < dom_hi || is_per[idim]) {
764  pbx.growHi(idim,-1);
765  }
766  }
767  }
768 
769  auto mf_arr = (m_rotate) ? rot_fields[imf]->const_array(mfi) :
770  fields[imf]->const_array(mfi);
771 
772  if (m_interp) {
773  const auto plo = geom.ProbLoArray();
774  const auto dxInv = geom.InvCellSizeArray();
775  const auto z_phys_arr = z_phys->const_array(mfi);
776  auto x_pos_arr = x_pos->array(mfi);
777  auto y_pos_arr = y_pos->array(mfi);
778  auto z_pos_arr = z_pos->array(mfi);
779  ParallelFor(Gpu::KernelInfo().setReduction(true), pbx, [=]
780  AMREX_GPU_DEVICE(int i, int j, int k, Gpu::Handler const& handler) noexcept
781  {
782  Real interp{0};
783  trilinear_interp_T(x_pos_arr(i,j,k), y_pos_arr(i,j,k), z_pos_arr(i,j,k),
784  &interp, mf_arr, z_phys_arr, plo, dxInv, 1);
785  Real val = interp;
786  Gpu::deviceReduceSum(&plane_avg[imf], val, handler);
787  });
788  } else {
789  auto k_arr = k_indx->const_array(mfi);
790  auto j_arr = j_indx ? j_indx->const_array(mfi) : Array4<const int> {};
791  auto i_arr = i_indx ? i_indx->const_array(mfi) : Array4<const int> {};
792  ParallelFor(Gpu::KernelInfo().setReduction(true), pbx, [=]
793  AMREX_GPU_DEVICE(int i, int j, int k, Gpu::Handler const& handler) noexcept
794  {
795  int mk = k_arr(i,j,k);
796  int mj = j_arr ? j_arr(i,j,k) : j;
797  int mi = i_arr ? i_arr(i,j,k) : i;
798  Real val = mf_arr(mi,mj,mk);
799  Gpu::deviceReduceSum(&plane_avg[imf], val, handler);
800  });
801  }
802  }
803  }
804 
805  //
806  //------------------------------------------------------------------------
807  // Averages for virtual potential temperature
808  // (This is cell-centered so we don't need to worry about double-counting)
809  //------------------------------------------------------------------------
810  //
811  if (fields[3]) // We have water vapor
812  {
813  int iavg = 4;
814  denom[iavg] = 1.0 / (Real)ncell_plane[iavg];
815  val_old[iavg] = plane_average[iavg]*d_fact_old;
816 
817 #ifdef _OPENMP
818 #pragma omp parallel if (Gpu::notInLaunchRegion())
819 #endif
820  for (MFIter mfi(*averages[iavg], TileNoZ()); mfi.isValid(); ++mfi)
821  {
822  Box pbx = mfi.tilebox();
823  pbx.setSmall(2,0); pbx.setBig(2,0);
824 
825  const Array4<Real const>& T_mf_arr = fields[2]->const_array(mfi);
826  const Array4<Real const>& qv_mf_arr = (fields[3])? fields[3]->const_array(mfi) : Array4<const Real>{};
827  const Array4<Real const>& qr_mf_arr = (fields[4])? fields[4]->const_array(mfi) : Array4<const Real>{};
828 
829  if (m_interp) {
830  const auto plo = m_geom[lev].ProbLoArray();
831  const auto dxInv = m_geom[lev].InvCellSizeArray();
832  const auto z_phys_arr = z_phys->const_array(mfi);
833  auto x_pos_arr = x_pos->array(mfi);
834  auto y_pos_arr = y_pos->array(mfi);
835  auto z_pos_arr = z_pos->array(mfi);
836  ParallelFor(Gpu::KernelInfo().setReduction(true), pbx, [=]
837  AMREX_GPU_DEVICE(int i, int j, int k, Gpu::Handler const& handler) noexcept
838  {
839  Real T_interp{0};
840  Real qv_interp{0};
841  trilinear_interp_T(x_pos_arr(i,j,k), y_pos_arr(i,j,k), z_pos_arr(i,j,k),
842  &T_interp, T_mf_arr, z_phys_arr, plo, dxInv, 1);
843  trilinear_interp_T(x_pos_arr(i,j,k), y_pos_arr(i,j,k), z_pos_arr(i,j,k),
844  &qv_interp, qv_mf_arr, z_phys_arr, plo, dxInv, 1);
845  Real vfac;
846  if (qr_mf_arr) {
847  // We also have liquid water
848  Real qr_interp{0};
849  trilinear_interp_T(x_pos_arr(i,j,k), y_pos_arr(i,j,k), z_pos_arr(i,j,k),
850  &qr_interp, qr_mf_arr, z_phys_arr, plo, dxInv, 1);
851  vfac = 1.0 + 0.61*qv_interp - qr_interp;
852  } else {
853  vfac = 1.0 + 0.61*qv_interp;
854  }
855  const Real val = T_interp * vfac;
856  Gpu::deviceReduceSum(&plane_avg[iavg], val, handler);
857  });
858  } else {
859  auto k_arr = k_indx->const_array(mfi);
860  auto j_arr = j_indx ? j_indx->const_array(mfi) : Array4<const int> {};
861  auto i_arr = i_indx ? i_indx->const_array(mfi) : Array4<const int> {};
862  ParallelFor(Gpu::KernelInfo().setReduction(true), pbx, [=]
863  AMREX_GPU_DEVICE(int i, int j, int k, Gpu::Handler const& handler) noexcept
864  {
865  int mk = k_arr(i,j,k);
866  int mj = j_arr ? j_arr(i,j,k) : j;
867  int mi = i_arr ? i_arr(i,j,k) : i;
868  Real vfac;
869  if (qr_mf_arr) {
870  // We also have liquid water
871  vfac = 1.0 + 0.61*qv_mf_arr(mi,mj,mk) - qr_mf_arr(mi,mj,mk);
872  } else {
873  vfac = 1.0 + 0.61*qv_mf_arr(mi,mj,mk);
874  }
875  const Real val = T_mf_arr(mi,mj,mk) * vfac;
876  Gpu::deviceReduceSum(&plane_avg[iavg], val, handler);
877  });
878  }
879  }
880  }
881  else // copy temperature
882  {
883  int iavg = m_navg - 2;
884  denom[iavg] = 1.0 / (Real)ncell_plane[iavg];
885  // plane_avg[iavg] = plane_avg[2]
886  Gpu::copy(Gpu::deviceToDevice, pavg.begin() + 2, pavg.begin() + 3,
887  pavg.begin() + iavg);
888  }
889 
890  //
891  //------------------------------------------------------------------------
892  // Averages for the tangential velocity magnitude
893  // (This is cell-centered so we don't need to worry about double-counting)
894  //------------------------------------------------------------------------
895  //
896  {
897  int imf = 0;
898  int iavg = m_navg - 1;
899  denom[iavg] = 1.0 / (Real)ncell_plane[iavg];
900  val_old[iavg] = plane_average[iavg]*d_fact_old;
901 
902  const Real Vsg = m_Vsg[lev];
903 
904 #ifdef _OPENMP
905 #pragma omp parallel if (Gpu::notInLaunchRegion())
906 #endif
907  for (MFIter mfi(*averages[iavg], TileNoZ()); mfi.isValid(); ++mfi)
908  {
909  Box pbx = mfi.tilebox();
910  pbx.setSmall(2,0); pbx.setBig(2,0);
911 
912  // Last element is Umag and always cell centered
913  auto u_mf_arr = (m_rotate) ? rot_fields[imf ]->const_array(mfi) :
914  fields[imf ]->const_array(mfi);
915  auto v_mf_arr = (m_rotate) ? rot_fields[imf+1]->const_array(mfi) :
916  fields[imf+1]->const_array(mfi);
917 
918  if (m_interp) {
919  const auto plo = m_geom[lev].ProbLoArray();
920  const auto dxInv = m_geom[lev].InvCellSizeArray();
921  const auto z_phys_arr = z_phys->const_array(mfi);
922  auto x_pos_arr = x_pos->array(mfi);
923  auto y_pos_arr = y_pos->array(mfi);
924  auto z_pos_arr = z_pos->array(mfi);
925  ParallelFor(Gpu::KernelInfo().setReduction(true), pbx, [=]
926  AMREX_GPU_DEVICE(int i, int j, int k, Gpu::Handler const& handler) noexcept
927  {
928  Real u_interp{0};
929  Real v_interp{0};
930  trilinear_interp_T(x_pos_arr(i,j,k), y_pos_arr(i,j,k), z_pos_arr(i,j,k),
931  &u_interp, u_mf_arr, z_phys_arr, plo, dxInv, 1);
932  trilinear_interp_T(x_pos_arr(i,j,k), y_pos_arr(i,j,k), z_pos_arr(i,j,k),
933  &v_interp, v_mf_arr, z_phys_arr, plo, dxInv, 1);
934  const Real val = std::sqrt(u_interp*u_interp + v_interp*v_interp + Vsg*Vsg);
935  Gpu::deviceReduceSum(&plane_avg[iavg], val, handler);
936  });
937  } else {
938  auto k_arr = k_indx->const_array(mfi);
939  auto j_arr = j_indx ? j_indx->const_array(mfi) : Array4<const int> {};
940  auto i_arr = i_indx ? i_indx->const_array(mfi) : Array4<const int> {};
941  ParallelFor(Gpu::KernelInfo().setReduction(true), pbx, [=]
942  AMREX_GPU_DEVICE(int i, int j, int k, Gpu::Handler const& handler) noexcept
943  {
944  int mk = k_arr(i,j,k);
945  int mj = j_arr ? j_arr(i,j,k) : j;
946  int mi = i_arr ? i_arr(i,j,k) : i;
947  const Real u_val = 0.5 * (u_mf_arr(mi,mj,mk) + u_mf_arr(mi+1,mj ,mk));
948  const Real v_val = 0.5 * (v_mf_arr(mi,mj,mk) + v_mf_arr(mi ,mj+1,mk));
949  const Real val = std::sqrt(u_val*u_val + v_val*v_val + Vsg*Vsg);
950  Gpu::deviceReduceSum(&plane_avg[iavg], val, handler);
951  });
952  }
953  }
954  }
955 
956  // Copy to host and sum across procs
957  Gpu::copy(Gpu::deviceToHost, pavg.begin(), pavg.end(), plane_average.begin());
958  ParallelDescriptor::ReduceRealSum(plane_average.data(), plane_average.size());
959 
960  // No spatial variation with plane averages
961  for (int iavg(0); iavg < m_navg; ++iavg){
962  plane_average[iavg] *= denom[iavg]*d_fact_new;
963  plane_average[iavg] += val_old[iavg];
964  averages[iavg]->setVal(plane_average[iavg]);
965  }
966 }
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
int m_navg
Definition: ERF_MOSTAverage.H:176
amrex::Vector< amrex::Vector< std::unique_ptr< amrex::MultiFab > > > m_averages
Definition: ERF_MOSTAverage.H:188
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_y_pos
Definition: ERF_MOSTAverage.H:183
amrex::Vector< std::unique_ptr< amrex::iMultiFab > > m_i_indx
Definition: ERF_MOSTAverage.H:185
amrex::Vector< amrex::MultiFab * > m_z_phys_nd
Definition: ERF_MOSTAverage.H:171
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_x_pos
Definition: ERF_MOSTAverage.H:182
amrex::Vector< amrex::Real > m_Vsg
Definition: ERF_MOSTAverage.H:217
amrex::Vector< amrex::Vector< std::unique_ptr< amrex::MultiFab > > > m_rot_fields
Definition: ERF_MOSTAverage.H:189
amrex::Vector< amrex::Vector< amrex::Real > > m_plane_average
Definition: ERF_MOSTAverage.H:194
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_z_pos
Definition: ERF_MOSTAverage.H:184
amrex::Vector< amrex::Vector< int > > m_ncell_plane
Definition: ERF_MOSTAverage.H:193
amrex::Real m_fact_new
Definition: ERF_MOSTAverage.H:212
amrex::Vector< std::unique_ptr< amrex::iMultiFab > > m_j_indx
Definition: ERF_MOSTAverage.H:186
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_fields
Definition: ERF_MOSTAverage.H:170
amrex::Real m_fact_old
Definition: ERF_MOSTAverage.H:212
bool m_interp
Definition: ERF_MOSTAverage.H:204
const amrex::Vector< amrex::Geometry > m_geom
Definition: ERF_MOSTAverage.H:169
AMREX_GPU_HOST_DEVICE static AMREX_INLINE void trilinear_interp_T(const amrex::Real &xp, const amrex::Real &yp, const amrex::Real &zp, amrex::Real *interp_vals, amrex::Array4< amrex::Real const > const &interp_array, amrex::Array4< amrex::Real const > const &z_arr, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &plo, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dxi, const int interp_comp)
Definition: ERF_MOSTAverage.H:110
amrex::Vector< std::unique_ptr< amrex::iMultiFab > > m_k_indx
Definition: ERF_MOSTAverage.H:187

Referenced by compute_averages().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compute_region_averages()

void MOSTAverage::compute_region_averages ( int  lev)

Function to compute average over local region.

Parameters
[in]levCurrent level
976 {
977  // Peel back the level
978  auto& fields = m_fields[lev];
979  auto& rot_fields = m_rot_fields[lev];
980  auto& averages = m_averages[lev];
981  const auto & geom = m_geom[lev];
982 
983  auto& z_phys = m_z_phys_nd[lev];
984  auto& x_pos = m_x_pos[lev];
985  auto& y_pos = m_y_pos[lev];
986  auto& z_pos = m_z_pos[lev];
987 
988  auto& i_indx = m_i_indx[lev];
989  auto& j_indx = m_j_indx[lev];
990  auto& k_indx = m_k_indx[lev];
991 
992  // Set factors for time averaging
993  Real d_fact_new, d_fact_old;
994  if (m_t_avg && m_t_init[lev]) {
995  d_fact_new = m_fact_new;
996  d_fact_old = m_fact_old;
997  } else {
998  d_fact_new = 1.0;
999  d_fact_old = 0.0;
1000  }
1001 
1002  // Number of cells contained in the local average
1003  const Real denom = 1.0 / (Real) m_ncell_region;
1004 
1005  // Capture radius for device
1006  int d_radius = m_radius;
1007 
1008  //
1009  //----------------------------------------------------------
1010  // Averages for U,V,T,Qv
1011  //----------------------------------------------------------
1012  //
1013  for (int imf(0); imf < 4; ++imf) {
1014 
1015  // Continue if no valid Qv pointer
1016  if (!fields[imf]) continue;
1017 
1018 #ifdef _OPENMP
1019 #pragma omp parallel if (Gpu::notInLaunchRegion())
1020 #endif
1021  for (MFIter mfi(*fields[imf], TileNoZ()); mfi.isValid(); ++mfi) {
1022  Box pbx = mfi.tilebox(); pbx.setSmall(2,0); pbx.setBig(2,0);
1023 
1024  auto mf_arr = (m_rotate) ? rot_fields[imf]->const_array(mfi) :
1025  fields[imf]->const_array(mfi);
1026  auto ma_arr = averages[imf]->array(mfi);
1027 
1028  if (m_interp) {
1029  const auto plo = geom.ProbLoArray();
1030  const auto dx = geom.CellSizeArray();
1031  const auto dxInv = geom.InvCellSizeArray();
1032  const auto z_phys_arr = z_phys->const_array(mfi);
1033  auto x_pos_arr = x_pos->array(mfi);
1034  auto y_pos_arr = y_pos->array(mfi);
1035  auto z_pos_arr = z_pos->array(mfi);
1036  ParallelFor(pbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
1037  {
1038  ma_arr(i,j,k) *= d_fact_old;
1039 
1040  Real met_h_zeta = Compute_h_zeta_AtCellCenter(i,j,k,dxInv,z_phys_arr);
1041  for (int lk(-d_radius); lk <= (d_radius); ++lk) {
1042  for (int lj(-d_radius); lj <= (d_radius); ++lj) {
1043  for (int li(-d_radius); li <= (d_radius); ++li) {
1044  Real interp{0};
1045  Real xp = x_pos_arr(i+li,j+lj,k);
1046  Real yp = y_pos_arr(i+li,j+lj,k);
1047  Real zp = z_pos_arr(i+li,j+lj,k) + met_h_zeta*lk*dx[2];
1048  trilinear_interp_T(xp, yp, zp, &interp, mf_arr, z_phys_arr, plo, dxInv, 1);
1049  Real val = denom * interp * d_fact_new;
1050  ma_arr(i,j,k) += val;
1051  }
1052  }
1053  }
1054  });
1055  } else {
1056  auto k_arr = k_indx->const_array(mfi);
1057  auto j_arr = j_indx ? j_indx->const_array(mfi) : Array4<const int> {};
1058  auto i_arr = i_indx ? i_indx->const_array(mfi) : Array4<const int> {};
1059  ParallelFor(pbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
1060  {
1061  ma_arr(i,j,k) *= d_fact_old;
1062 
1063  int mk = k_arr(i,j,k);
1064  int mj = j_arr ? j_arr(i,j,k) : j;
1065  int mi = i_arr ? i_arr(i,j,k) : i;
1066  for (int lk(mk-d_radius); lk <= (mk+d_radius); ++lk) {
1067  for (int lj(mj-d_radius); lj <= (mj+d_radius); ++lj) {
1068  for (int li(mi-d_radius); li <= (mi+d_radius); ++li) {
1069  Real val = denom * mf_arr(li, lj, lk) * d_fact_new;
1070  ma_arr(i,j,k) += val;
1071  }
1072  }
1073  }
1074  });
1075  }
1076  }
1077 
1078  // Fill interior ghost cells and any ghost cells outside a periodic domain
1079  //***********************************************************************************
1080  averages[imf]->FillBoundary(geom.periodicity());
1081  }
1082 
1083  //
1084  //----------------------------------------------------------
1085  // Averages for virtual potential temperature
1086  //----------------------------------------------------------
1087  //
1088  if (fields[3]) // We have water vapor
1089  {
1090  int iavg = 4;
1091 
1092 #ifdef _OPENMP
1093 #pragma omp parallel if (Gpu::notInLaunchRegion())
1094 #endif
1095  for (MFIter mfi(*averages[iavg], TileNoZ()); mfi.isValid(); ++mfi) {
1096  Box pbx = mfi.tilebox(); pbx.setSmall(2,0); pbx.setBig(2,0);
1097 
1098  const Array4<Real const>& T_mf_arr = fields[2]->const_array(mfi);
1099  const Array4<Real const>& qv_mf_arr = (fields[3])? fields[3]->const_array(mfi) : Array4<const Real>{};
1100  const Array4<Real const>& qr_mf_arr = (fields[4])? fields[4]->const_array(mfi) : Array4<const Real>{};
1101  auto ma_arr = averages[iavg]->array(mfi);
1102 
1103  if (m_interp) {
1104  const auto plo = geom.ProbLoArray();
1105  const auto dx = geom.CellSizeArray();
1106  const auto dxInv = geom.InvCellSizeArray();
1107  const auto z_phys_arr = z_phys->const_array(mfi);
1108  auto x_pos_arr = x_pos->array(mfi);
1109  auto y_pos_arr = y_pos->array(mfi);
1110  auto z_pos_arr = z_pos->array(mfi);
1111  ParallelFor(pbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
1112  {
1113  ma_arr(i,j,k) *= d_fact_old;
1114 
1115  Real met_h_zeta = Compute_h_zeta_AtCellCenter(i,j,k,dxInv,z_phys_arr);
1116  for (int lk(-d_radius); lk <= (d_radius); ++lk) {
1117  for (int lj(-d_radius); lj <= (d_radius); ++lj) {
1118  for (int li(-d_radius); li <= (d_radius); ++li) {
1119  Real T_interp{0};
1120  Real qv_interp{0};
1121  Real xp = x_pos_arr(i+li,j+lj,k);
1122  Real yp = y_pos_arr(i+li,j+lj,k);
1123  Real zp = z_pos_arr(i+li,j+lj,k) + met_h_zeta*lk*dx[2];
1124  trilinear_interp_T(xp, yp, zp, &T_interp, T_mf_arr, z_phys_arr, plo, dxInv, 1);
1125  trilinear_interp_T(xp, yp, zp, &qv_interp, qv_mf_arr, z_phys_arr, plo, dxInv, 1);
1126  Real vfac;
1127  if (qr_mf_arr) {
1128  // We also have liquid water
1129  Real qr_interp{0};
1130  trilinear_interp_T(x_pos_arr(i,j,k), y_pos_arr(i,j,k), z_pos_arr(i,j,k),
1131  &qr_interp, qr_mf_arr, z_phys_arr, plo, dxInv, 1);
1132  vfac = 1.0 + 0.61*qv_interp - qr_interp;
1133  } else {
1134  vfac = 1.0 + 0.61*qv_interp;
1135  }
1136  const Real mag = T_interp * vfac;
1137  const Real val = denom * mag * d_fact_new;
1138  ma_arr(i,j,k) += val;
1139  }
1140  }
1141  }
1142  });
1143  } else {
1144  auto k_arr = k_indx->const_array(mfi);
1145  auto j_arr = j_indx ? j_indx->const_array(mfi) : Array4<const int> {};
1146  auto i_arr = i_indx ? i_indx->const_array(mfi) : Array4<const int> {};
1147  ParallelFor(pbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
1148  {
1149  ma_arr(i,j,k) *= d_fact_old;
1150 
1151  int mk = k_arr(i,j,k);
1152  int mj = j_arr ? j_arr(i,j,k) : j;
1153  int mi = i_arr ? i_arr(i,j,k) : i;
1154  for (int lk(mk-d_radius); lk <= (mk+d_radius); ++lk) {
1155  for (int lj(mj-d_radius); lj <= (mj+d_radius); ++lj) {
1156  for (int li(mi-d_radius); li <= (mi+d_radius); ++li) {
1157  Real vfac;
1158  if (qr_mf_arr) {
1159  // We also have liquid water
1160  vfac = 1.0 + 0.61*qv_mf_arr(li,lj,lk) - qr_mf_arr(li,lj,lk);
1161  } else {
1162  vfac = 1.0 + 0.61*qv_mf_arr(li,lj,lk);
1163  }
1164  const Real mag = T_mf_arr(li,lj,lk) * vfac;
1165  const Real val = denom * mag * d_fact_new;
1166  ma_arr(i,j,k) += val;
1167  }
1168  }
1169  }
1170  });
1171  }
1172 
1173  // Fill interior ghost cells and any ghost cells outside a periodic domain
1174  //***********************************************************************************
1175  averages[iavg]->FillBoundary(geom.periodicity());
1176  }
1177  }
1178  else // copy temperature
1179  {
1180  int iavg = m_navg - 2;
1181  IntVect ng = averages[iavg]->nGrowVect();
1182  MultiFab::Copy(*(averages[iavg]),*(averages[2]),0,0,1,ng);
1183  }
1184 
1185  //
1186  //----------------------------------------------------------
1187  // Averages for the tangential velocity magnitude
1188  //----------------------------------------------------------
1189  //
1190  {
1191  int imf = 0;
1192  int iavg = m_navg - 1;
1193 
1194  const Real Vsg = m_Vsg[lev];
1195 
1196 #ifdef _OPENMP
1197 #pragma omp parallel if (Gpu::notInLaunchRegion())
1198 #endif
1199  for (MFIter mfi(*averages[iavg], TileNoZ()); mfi.isValid(); ++mfi) {
1200  Box pbx = mfi.tilebox(); pbx.setSmall(2,0); pbx.setBig(2,0);
1201 
1202  auto u_mf_arr = (m_rotate) ? rot_fields[imf ]->const_array(mfi) :
1203  fields[imf ]->const_array(mfi);
1204  auto v_mf_arr = (m_rotate) ? rot_fields[imf+1]->const_array(mfi) :
1205  fields[imf+1]->const_array(mfi);
1206  auto ma_arr = averages[iavg]->array(mfi);
1207 
1208  if (m_interp) {
1209  const auto plo = geom.ProbLoArray();
1210  const auto dx = geom.CellSizeArray();
1211  const auto dxInv = geom.InvCellSizeArray();
1212  const auto z_phys_arr = z_phys->const_array(mfi);
1213  auto x_pos_arr = x_pos->array(mfi);
1214  auto y_pos_arr = y_pos->array(mfi);
1215  auto z_pos_arr = z_pos->array(mfi);
1216  ParallelFor(pbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
1217  {
1218  ma_arr(i,j,k) *= d_fact_old;
1219 
1220  Real met_h_zeta = Compute_h_zeta_AtCellCenter(i,j,k,dxInv,z_phys_arr);
1221  for (int lk(-d_radius); lk <= (d_radius); ++lk) {
1222  for (int lj(-d_radius); lj <= (d_radius); ++lj) {
1223  for (int li(-d_radius); li <= (d_radius); ++li) {
1224  Real u_interp{0};
1225  Real v_interp{0};
1226  Real xp = x_pos_arr(i+li,j+lj,k);
1227  Real yp = y_pos_arr(i+li,j+lj,k);
1228  Real zp = z_pos_arr(i+li,j+lj,k) + met_h_zeta*lk*dx[2];
1229  trilinear_interp_T(xp, yp, zp, &u_interp, u_mf_arr, z_phys_arr, plo, dxInv, 1);
1230  trilinear_interp_T(xp, yp, zp, &v_interp, v_mf_arr, z_phys_arr, plo, dxInv, 1);
1231  const Real mag = std::sqrt(u_interp*u_interp + v_interp*v_interp + Vsg*Vsg);
1232  Real val = denom * mag * d_fact_new;
1233  ma_arr(i,j,k) += val;
1234  }
1235  }
1236  }
1237  });
1238  } else {
1239  auto k_arr = k_indx->const_array(mfi);
1240  auto j_arr = j_indx ? j_indx->const_array(mfi) : Array4<const int> {};
1241  auto i_arr = i_indx ? i_indx->const_array(mfi) : Array4<const int> {};
1242  ParallelFor(pbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
1243  {
1244  ma_arr(i,j,k) *= d_fact_old;
1245 
1246  int mk = k_arr(i,j,k);
1247  int mj = j_arr ? j_arr(i,j,k) : j;
1248  int mi = i_arr ? i_arr(i,j,k) : i;
1249  for (int lk(mk-d_radius); lk <= (mk+d_radius); ++lk) {
1250  for (int lj(mj-d_radius); lj <= (mj+d_radius); ++lj) {
1251  for (int li(mi-d_radius); li <= (mi+d_radius); ++li) {
1252  const Real u_val = 0.5 * (u_mf_arr(li,lj,lk) + u_mf_arr(li+1,lj ,lk));
1253  const Real v_val = 0.5 * (v_mf_arr(li,lj,lk) + v_mf_arr(li ,lj+1,lk));
1254  const Real mag = std::sqrt(u_val*u_val + v_val*v_val + Vsg*Vsg);
1255  Real val = denom * mag * d_fact_new;
1256  ma_arr(i,j,k) += val;
1257  }
1258  }
1259  }
1260  });
1261  }
1262 
1263  // Fill interior ghost cells and any ghost cells outside a periodic domain
1264  //***********************************************************************************
1265  averages[iavg]->FillBoundary(geom.periodicity());
1266  }
1267  }
1268 
1269 
1270  // Need to fill ghost cells outside the domain if not periodic
1271  bool not_per_x = !(geom.periodicity().isPeriodic(0));
1272  bool not_per_y = !(geom.periodicity().isPeriodic(1));
1273  if (not_per_x || not_per_y) {
1274  Box domain = geom.Domain();
1275  for (int iavg(0); iavg < m_navg; ++iavg) {
1276  IndexType ixt = averages[iavg]->boxArray().ixType();
1277  Box ldomain = domain; ldomain.convert(ixt);
1278  IntVect ng = averages[iavg]->nGrowVect(); ng[2]=0;
1279 #ifdef _OPENMP
1280 #pragma omp parallel if (Gpu::notInLaunchRegion())
1281 #endif
1282  for (MFIter mfi(*averages[iavg], TileNoZ()); mfi.isValid(); ++mfi) {
1283  Box gpbx = mfi.growntilebox(ng); gpbx.setSmall(2,0); gpbx.setBig(2,0);
1284 
1285  if (ldomain.contains(gpbx)) continue;
1286 
1287  auto ma_arr = averages[iavg]->array(mfi);
1288 
1289  int i_lo = ldomain.smallEnd(0); int i_hi = ldomain.bigEnd(0);
1290  int j_lo = ldomain.smallEnd(1); int j_hi = ldomain.bigEnd(1);
1291  ParallelFor(gpbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
1292  {
1293  int li, lj;
1294  li = i < i_lo ? i_lo : i;
1295  li = li > i_hi ? i_hi : li;
1296  lj = j < j_lo ? j_lo : j;
1297  lj = lj > j_hi ? j_hi : lj;
1298 
1299  ma_arr(i,j,k) = ma_arr(li,lj,k);
1300  });
1301  } // MFiter
1302  } // iavg
1303  } // Not periodic
1304 }
AMREX_FORCE_INLINE AMREX_GPU_DEVICE amrex::Real Compute_h_zeta_AtCellCenter(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:39
int m_radius
Definition: ERF_MOSTAverage.H:198
int m_ncell_region
Definition: ERF_MOSTAverage.H:199

Referenced by compute_averages().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_average()

const amrex::MultiFab* MOSTAverage::get_average ( int  lev,
int  comp 
) const
inline
92 { return m_averages[lev][comp].get(); }

Referenced by ABLMost::get_mac_avg().

Here is the caller graph for this function:

◆ get_zref()

amrex::Real MOSTAverage::get_zref ( ) const
inline
95 { return m_zref; }
amrex::Real m_zref
Definition: ERF_MOSTAverage.H:180

Referenced by ABLMost::get_zref().

Here is the caller graph for this function:

◆ operator=() [1/2]

MOSTAverage& MOSTAverage::operator= ( const MOSTAverage other)
delete

◆ operator=() [2/2]

MOSTAverage& MOSTAverage::operator= ( MOSTAverage &&  other)
deletenoexcept

◆ set_k_indices_N()

void MOSTAverage::set_k_indices_N ( )

Function to set K indices without terrain.

368 {
369  ParmParse pp(m_pp_prefix);
370  auto read_z = pp.query("most.zref",m_zref);
371  auto read_k = pp.queryarr("most.k_arr_in",m_k_in);
372 
373  // Default behavior is to use the first cell center
374  if (!read_z && !read_k) {
375  Real m_zlo = m_geom[0].ProbLo(2);
376  Real m_dz = m_geom[0].CellSize(2);
377  m_zref = m_zlo + 0.5 * m_dz;
378  Print() << "Reference height for MOST set to " << m_zref << std::endl;
379  read_z = true;
380  }
381 
382  // Specify z_ref & compute k_indx (z_ref takes precedence)
383  if (read_z) {
384  for (int lev(0); lev < m_maxlev; lev++) {
385  Real m_zlo = m_geom[lev].ProbLo(2);
386  Real m_zhi = m_geom[lev].ProbHi(2);
387  Real m_dz = m_geom[lev].CellSize(2);
388 
389  amrex::ignore_unused(m_zhi);
390 
391  AMREX_ASSERT_WITH_MESSAGE(m_zref >= m_zlo + 0.5 * m_dz,
392  "Query point must be past first z-cell!");
393 
394  AMREX_ASSERT_WITH_MESSAGE(m_zref <= m_zhi - 0.5 * m_dz,
395  "Query point must be below the last z-cell!");
396 
397  int lk = static_cast<int>(floor((m_zref - m_zlo) / m_dz - 0.5));
398 
399  m_zref = (lk + 0.5) * m_dz + m_zlo;
400 
401  AMREX_ALWAYS_ASSERT(lk >= m_radius);
402 
403  m_k_indx[lev]->setVal(lk);
404  }
405  // Specified k_indx & compute z_ref
406  } else if (read_k) {
407  for (int lev(0); lev < m_maxlev; lev++){
408  AMREX_ASSERT_WITH_MESSAGE(m_k_in[lev] >= m_radius,
409  "K index must be larger than averaging radius!");
410  m_k_indx[lev]->setVal(m_k_in[lev]);
411  }
412 
413  // TODO: check that z_ref is constant across levels
414  Real m_zlo = m_geom[0].ProbLo(2);
415  Real m_dz = m_geom[0].CellSize(2);
416  m_zref = ((Real)m_k_in[0] + 0.5) * m_dz + m_zlo;
417  }
418 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pp(amrex::Real y)
Definition: ERF_MicrophysicsUtils.H:219
std::string m_pp_prefix
Definition: ERF_MOSTAverage.H:181
int m_maxlev
Definition: ERF_MOSTAverage.H:177
amrex::Vector< int > m_k_in
Definition: ERF_MOSTAverage.H:200
Here is the call graph for this function:

◆ set_k_indices_T()

void MOSTAverage::set_k_indices_T ( )

Function to set K indices with terrain.

427 {
428  ParmParse pp(m_pp_prefix);
429  auto read_z = pp.query("most.zref",m_zref);
430  auto read_k = pp.queryarr("most.k_arr_in",m_k_in);
431 
432  // No default behavior with terrain (we can't tell the difference between
433  // vertical grid stretching and true terrain)
434  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(read_z != read_k,
435  "Need to specify zref or k_arr_in for MOST");
436 
437  // Capture for device
438  Real d_zref = m_zref;
439  Real d_radius = m_radius;
440  amrex::ignore_unused(d_radius);
441 
442  // Specify z_ref & compute k_indx (z_ref takes precedence)
443  if (read_z) {
444  for (int lev(0); lev < m_maxlev; lev++) {
445  int kmax = m_geom[lev].Domain().bigEnd(2);
446  for (MFIter mfi(*m_k_indx[lev], TileNoZ()); mfi.isValid(); ++mfi) {
447  Box npbx = mfi.tilebox(IntVect(1,1,0),IntVect(1,1,0));
448  const auto z_phys_arr = m_z_phys_nd[lev]->const_array(mfi);
449  auto k_arr = m_k_indx[lev]->array(mfi);
450  ParallelFor(npbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
451  {
452  k_arr(i,j,k) = 0;
453  Real z_bot_face = 0.25 * ( z_phys_arr(i ,j ,k) + z_phys_arr(i+1,j ,k)
454  + z_phys_arr(i ,j+1,k) + z_phys_arr(i+1,j+1,k) );
455  Real z_target = z_bot_face + d_zref;
456  for (int lk(0); lk<=kmax; ++lk) {
457  Real z_lo = 0.25 * ( z_phys_arr(i,j ,lk ) + z_phys_arr(i+1,j ,lk )
458  + z_phys_arr(i,j+1,lk ) + z_phys_arr(i+1,j+1,lk ) );
459  Real z_hi = 0.25 * ( z_phys_arr(i,j ,lk+1) + z_phys_arr(i+1,j ,lk+1)
460  + z_phys_arr(i,j+1,lk+1) + z_phys_arr(i+1,j+1,lk+1) );
461  if (z_target > z_lo && z_target < z_hi){
462  AMREX_ASSERT_WITH_MESSAGE(lk >= d_radius,
463  "K index must be larger than averaging radius!");
464  k_arr(i,j,k) = lk;
465  break;
466  }
467  }
468  });
469  }
470  }
471  // Specified k_indx & compute z_ref
472  } else if (read_k) {
473  AMREX_ASSERT_WITH_MESSAGE(false, "Specified k-indx with terrain not implemented!");
474  }
475 }
Here is the call graph for this function:

◆ set_norm_indices_T()

void MOSTAverage::set_norm_indices_T ( )

Function to set I,J,K indices with terrain normals.

484 {
485  ParmParse pp(m_pp_prefix);
486  pp.get("most.zref",m_zref);
487 
488  // Capture for device
489  Real d_zref = m_zref;
490  Real d_radius = m_radius;
491 
492  for (int lev(0); lev < m_maxlev; lev++) {
493  int kmax = m_geom[lev].Domain().bigEnd(2);
494  const auto dxInv = m_geom[lev].InvCellSizeArray();
495  IntVect ng = m_k_indx[lev]->nGrowVect(); ng[2]=0;
496  for (MFIter mfi(*m_k_indx[lev], TileNoZ()); mfi.isValid(); ++mfi) {
497  Box npbx = mfi.tilebox(IntVect(1,1,0),IntVect(1,1,0));
498  Box gpbx = mfi.growntilebox(ng);
499  const auto z_phys_arr = m_z_phys_nd[lev]->const_array(mfi);
500  auto i_arr = m_i_indx[lev]->array(mfi);
501  auto j_arr = m_j_indx[lev]->array(mfi);
502  auto k_arr = m_k_indx[lev]->array(mfi);
503  ParallelFor(npbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
504  {
505  // Elements of normal vector
506  Real met_h_xi = Compute_h_xi_AtCellCenter (i,j,k,dxInv,z_phys_arr);
507  Real met_h_eta = Compute_h_eta_AtCellCenter(i,j,k,dxInv,z_phys_arr);
508  Real mag = std::sqrt(met_h_xi*met_h_xi + met_h_eta*met_h_eta + 1.0);
509 
510  // Unit-normal vector scaled by z_ref
511  Real delta_x = -met_h_xi/mag * d_zref;
512  Real delta_y = -met_h_eta/mag * d_zref;
513  Real delta_z = 1.0/mag * d_zref;
514 
515  // Compute i & j as displacements (no grid stretching)
516  int delta_i = static_cast<int>(std::round(delta_x*dxInv[0]));
517  int delta_j = static_cast<int>(std::round(delta_y*dxInv[1]));
518  int i_new = i + delta_i;
519  int j_new = j + delta_j;
520  i_arr(i,j,k) = i_new;
521  j_arr(i,j,k) = j_new;
522 
523  // Search for k (grid is stretched in z)
524  Real z_bot_face = 0.25 * ( z_phys_arr(i ,j ,k) + z_phys_arr(i+1,j ,k)
525  + z_phys_arr(i ,j+1,k) + z_phys_arr(i+1,j+1,k) );
526  Real z_target = z_bot_face + delta_z;
527  for (int lk(0); lk<=kmax; ++lk) {
528  Real z_lo = 0.25 * ( z_phys_arr(i_new,j_new ,lk ) + z_phys_arr(i_new+1,j_new ,lk )
529  + z_phys_arr(i_new,j_new+1,lk ) + z_phys_arr(i_new+1,j_new+1,lk ) );
530  Real z_hi = 0.25 * ( z_phys_arr(i_new,j_new ,lk+1) + z_phys_arr(i_new+1,j_new ,lk+1)
531  + z_phys_arr(i_new,j_new+1,lk+1) + z_phys_arr(i_new+1,j_new+1,lk+1) );
532  if (z_target > z_lo && z_target < z_hi){
533  AMREX_ASSERT_WITH_MESSAGE(lk >= d_radius,
534  "K index must be larger than averaging radius!");
535  amrex::ignore_unused(d_radius);
536  k_arr(i,j,k) = lk;
537  break;
538  }
539  }
540 
541  // Destination cell must be contained on the current process!
542  amrex::ignore_unused(gpbx);
543  AMREX_ASSERT_WITH_MESSAGE(gpbx.contains(i_arr(i,j,k),j_arr(i,j,k),k_arr(i,j,k)),
544  "Query index outside of proc domain!");
545  });
546  }
547  }
548 }
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_AtCellCenter(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:69
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_AtCellCenter(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:54
Here is the call graph for this function:

◆ set_norm_positions_T()

void MOSTAverage::set_norm_positions_T ( )

Function to set positions with terrain and normal vector.

603 {
604  ParmParse pp(m_pp_prefix);
605  pp.get("most.zref",m_zref);
606 
607  // Capture for device
608  Real d_zref = m_zref;
609 
610  for (int lev(0); lev < m_maxlev; lev++) {
611  RealVect base;
612  const auto dx = m_geom[lev].CellSizeArray();
613  const auto dxInv = m_geom[lev].InvCellSizeArray();
614  IntVect ng = m_x_pos[lev]->nGrowVect(); ng[2]=0;
615  for (MFIter mfi(*m_x_pos[lev], TileNoZ()); mfi.isValid(); ++mfi) {
616  Box npbx = mfi.tilebox(IntVect(1,1,0),IntVect(1,1,0));
617  Box gpbx = mfi.growntilebox(ng);
618  RealBox grb{gpbx,dx.data(),base.dataPtr()};
619 
620  const auto z_phys_arr = m_z_phys_nd[lev]->const_array(mfi);
621  auto x_pos_arr = m_x_pos[lev]->array(mfi);
622  auto y_pos_arr = m_y_pos[lev]->array(mfi);
623  auto z_pos_arr = m_z_pos[lev]->array(mfi);
624  ParallelFor(npbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
625  {
626  // Elements of normal vector
627  Real met_h_xi = Compute_h_xi_AtCellCenter (i,j,k,dxInv,z_phys_arr);
628  Real met_h_eta = Compute_h_eta_AtCellCenter(i,j,k,dxInv,z_phys_arr);
629  Real mag = std::sqrt(met_h_xi*met_h_xi + met_h_eta*met_h_eta + 1.0);
630 
631  // Unit-normal vector scaled by z_ref
632  Real delta_x = -met_h_xi/mag * d_zref;
633  Real delta_y = -met_h_eta/mag * d_zref;
634  Real delta_z = 1.0/mag * d_zref;
635 
636  // Position of the current node (indx:0,0,1)
637  Real x0 = ((Real) i + 0.5) * dx[0];
638  Real y0 = ((Real) j + 0.5) * dx[1];
639 
640  // Final position at end of vector
641  x_pos_arr(i,j,k) = x0 + delta_x;
642  y_pos_arr(i,j,k) = y0 + delta_y;
643  Real z_bot_face = 0.25 * ( z_phys_arr(i ,j ,k) + z_phys_arr(i+1,j ,k)
644  + z_phys_arr(i ,j+1,k) + z_phys_arr(i+1,j+1,k) );
645  z_pos_arr(i,j,k) = z_bot_face + delta_z;
646 
647  // Destination position must be contained on the current process!
648  Real pos[] = {x_pos_arr(i,j,k),y_pos_arr(i,j,k),0.5*dx[2]};
649  amrex::ignore_unused(pos);
650  AMREX_ASSERT_WITH_MESSAGE( grb.contains(&pos[0]),
651  "Query point outside of proc domain!");
652  });
653  }
654  }
655 }
Here is the call graph for this function:

◆ set_plane_normalization()

void MOSTAverage::set_plane_normalization ( )

Function to compute normalization for plane average.

307 {
308  // Cells per plane and temp avg storage
309  m_ncell_plane.resize(m_maxlev);
310  m_plane_average.resize(m_maxlev);
311 
312  for (int lev(0); lev < m_maxlev; lev++) {
313  // True domain not used for normalization
314  Box domain = m_geom[lev].Domain();
315 
316  // NOTE: Level 0 spans the whole domain, but finer
317  // levels do not have such a restriction.
318  // For now, use the bounding box of the boxArray
319  // for normalization, consistent with avg routine.
320 
321  // Bounded box of CC data used for normalization
322  Box bnd_bx = (m_fields[lev][2]->boxArray()).minimalBox();
323 
324  // NOTE: Bounding box must lie on the periodic boundaries
325  // in order to trip the is_per flag
326 
327  // Num components, plane avg, cells per plane
328  Array<int,AMREX_SPACEDIM> is_per = {0,0,0};
329  for (int idim(0); idim < AMREX_SPACEDIM-1; ++idim) {
330  if ( m_geom[lev].isPeriodic(idim) &&
331  bnd_bx.bigEnd(idim)==domain.bigEnd(idim) &&
332  bnd_bx.smallEnd(idim)==domain.smallEnd(idim) ) { is_per[idim] = 1; }
333  }
334 
335  m_ncell_plane[lev].resize(m_navg);
336  m_plane_average[lev].resize(m_navg);
337  for (int iavg(0); iavg < m_navg; ++iavg) {
338  // Convert bnd_bx to current index type
339  IndexType ixt = m_averages[lev][iavg]->boxArray().ixType();
340  bnd_bx.convert(ixt);
341  IntVect bnd_bx_lo(bnd_bx.loVect());
342  IntVect bnd_bx_hi(bnd_bx.hiVect());
343 
344  m_plane_average[lev][iavg] = 0.0;
345 
346  m_ncell_plane[lev][iavg] = 1;
347  for (int idim(0); idim < AMREX_SPACEDIM; ++idim) {
348  if (idim != 2) {
349  if (ixt.nodeCentered(idim) && is_per[idim]) {
350  m_ncell_plane[lev][iavg] *= (bnd_bx_hi[idim] - bnd_bx_lo[idim]);
351  } else {
352  m_ncell_plane[lev][iavg] *= (bnd_bx_hi[idim] - bnd_bx_lo[idim] + 1);
353  }
354  }
355  } // idim
356  } // iavg
357  } // lev
358 
359 }

◆ set_region_normalization()

void MOSTAverage::set_region_normalization ( )
inline
53  {m_ncell_region = (2 * m_radius + 1) * (2 * m_radius + 1) * (2 * m_radius + 1);}

◆ set_rotated_fields()

void MOSTAverage::set_rotated_fields ( int  lev)

Function to set the rotated velocities.

248 {
249  // Peel back the level
250  auto& fields = m_fields[lev];
251  auto& rot_fields = m_rot_fields[lev];
252  auto z_phys_nd = m_z_phys_nd[lev];
253 
254  // Inverse grid size
255  const auto dxInv = m_geom[lev].InvCellSizeArray();
256 
257  // Single MFIter over CC data
258  int imf_cc = 2;
259 
260  // Populate rotated U & V for terrain
261 #ifdef _OPENMP
262 #pragma omp parallel if (Gpu::notInLaunchRegion())
263 #endif
264  for (MFIter mfi(*fields[imf_cc], TileNoZ()); mfi.isValid(); ++mfi) {
265  Box ubx = mfi.tilebox(IntVect(1,0,0));
266  Box vbx = mfi.tilebox(IntVect(0,1,0));
267 
268  const Array4<const Real>& z_phys_arr = z_phys_nd->const_array(mfi);
269 
270  const Array4<const Real>& u_arr = fields[0]->const_array(mfi);
271  const Array4<const Real>& v_arr = fields[1]->const_array(mfi);
272  const Array4<const Real>& w_arr = fields[4]->const_array(mfi);
273 
274  const Array4<Real>& u_rot_arr = rot_fields[0]->array(mfi);
275  const Array4<Real>& v_rot_arr = rot_fields[1]->array(mfi);
276 
277  // U rotated magnitude
278  ParallelFor(ubx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
279  {
280  // Elements of first tangent vector
281  Real met_h_xi = Compute_h_xi_AtIface(i,j,k,dxInv,z_phys_arr);
282  u_rot_arr(i,j,k) = (u_arr(i,j,k) + met_h_xi*w_arr(i,j,k))
283  / std::sqrt(met_h_xi*met_h_xi + 1.0);
284  });
285 
286  // V rotated magnitude
287  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
288  {
289  // Elements of second tangent vector
290  Real met_h_eta = Compute_h_eta_AtJface(i,j,k,dxInv,z_phys_arr);
291  v_rot_arr(i,j,k) = (v_arr(i,j,k) + met_h_eta*w_arr(i,j,k))
292  / std::sqrt(met_h_eta*met_h_eta + 1.0);
293  });
294  }
295 
296  // Direct copy of other scalar variables
297  MultiFab::Copy(*rot_fields[2],*fields[2],0,0,1,rot_fields[2]->nGrowVect());
298  if (fields[3]) MultiFab::Copy(*rot_fields[3],*fields[3],0,0,1,rot_fields[3]->nGrowVect());
299 }
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_AtIface(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:101
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_AtJface(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:158

Referenced by compute_averages().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_z_positions_T()

void MOSTAverage::set_z_positions_T ( )

Function to set positions with terrain and e_z vector.

557 {
558  ParmParse pp(m_pp_prefix);
559  pp.get("most.zref",m_zref);
560 
561  // Capture for device
562  Real d_zref = m_zref;
563 
564  for (int lev(0); lev < m_maxlev; lev++) {
565  RealVect base;
566  const auto dx = m_geom[lev].CellSizeArray();
567  IntVect ng = m_x_pos[lev]->nGrowVect(); ng[2]=0;
568  for (MFIter mfi(*m_x_pos[lev], TileNoZ()); mfi.isValid(); ++mfi) {
569  Box npbx = mfi.tilebox(IntVect(1,1,0),IntVect(1,1,0));
570  Box gpbx = mfi.growntilebox(ng);
571  RealBox grb{gpbx,dx.data(),base.dataPtr()};
572 
573  const auto z_phys_arr = m_z_phys_nd[lev]->const_array(mfi);
574  auto x_pos_arr = m_x_pos[lev]->array(mfi);
575  auto y_pos_arr = m_y_pos[lev]->array(mfi);
576  auto z_pos_arr = m_z_pos[lev]->array(mfi);
577  ParallelFor(npbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
578  {
579  // Final position at end of vector
580  x_pos_arr(i,j,k) = ((Real) i + 0.5) * dx[0];
581  y_pos_arr(i,j,k) = ((Real) j + 0.5) * dx[1];
582  Real z_bot_face = 0.25 * ( z_phys_arr(i ,j ,k) + z_phys_arr(i+1,j ,k)
583  + z_phys_arr(i ,j+1,k) + z_phys_arr(i+1,j+1,k) );
584  z_pos_arr(i,j,k) = z_bot_face + d_zref;
585 
586  // Destination position must be contained on the current process!
587  Real pos[] = {x_pos_arr(i,j,k),y_pos_arr(i,j,k),0.5*dx[2]};
588  amrex::ignore_unused(pos);
589  AMREX_ASSERT_WITH_MESSAGE( grb.contains(&pos[0]),
590  "Query point outside of proc domain!");
591  });
592  }
593  }
594 }
Here is the call graph for this function:

◆ trilinear_interp_T()

AMREX_GPU_HOST_DEVICE static AMREX_INLINE void MOSTAverage::trilinear_interp_T ( const amrex::Real &  xp,
const amrex::Real &  yp,
const amrex::Real &  zp,
amrex::Real *  interp_vals,
amrex::Array4< amrex::Real const > const &  interp_array,
amrex::Array4< amrex::Real const > const &  z_arr,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  plo,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  dxi,
const int  interp_comp 
)
inlinestatic

Function to compute trilinear interpolation with terrain.

Parameters
[in]xpX-position
[in]ypY-position
[out]interp_valsValues interpolated
[in]interp_arrayArray to interpolate on
[in]z_arrPhysical heights
[in]ploProblem lower bounds
[in]dxiInverse cell size array
[in]interp_compNumber of components to interpolate
119  {
120  // Search to get z/k
121  bool found = false;
122  amrex::Real zval= 0.0;
123  int kmax = ubound(z_arr).z;
124  int i_new = (int) (xp * dxi[0] - 0.5);
125  int j_new = (int) (yp * dxi[1] - 0.5);
126  amrex::Real z_target = zp;
127  for (int lk(0); lk<kmax; ++lk) {
128  amrex::Real z_lo = 0.25 * ( z_arr(i_new,j_new ,lk ) + z_arr(i_new+1,j_new ,lk )
129  + z_arr(i_new,j_new+1,lk ) + z_arr(i_new+1,j_new+1,lk ) );
130  amrex::Real z_hi = 0.25 * ( z_arr(i_new,j_new ,lk+1) + z_arr(i_new+1,j_new ,lk+1)
131  + z_arr(i_new,j_new+1,lk+1) + z_arr(i_new+1,j_new+1,lk+1) );
132  if (z_target > z_lo && z_target < z_hi){
133  found = true;
134  zval = (amrex::Real) lk + ((z_target - z_lo) / (z_hi - z_lo)) + 0.5;
135  break;
136  }
137  }
138 
139  amrex::ignore_unused(found);
140  AMREX_ASSERT_WITH_MESSAGE(found, "MOSTAverage: Height above terrain not found, try increasing z_ref!");
141 
142  const amrex::RealVect lx((xp - plo[0])*dxi[0] + 0.5,
143  (yp - plo[1])*dxi[1] + 0.5,
144  zval);
145 
146  const amrex::IntVect ijk = lx.floor();
147 
148  int i = ijk[0]; int j = ijk[1]; int k = ijk[2];
149 
150  // Weights
151  const amrex::RealVect sx_hi = lx - ijk;
152  const amrex::RealVect sx_lo = 1.0 - sx_hi;
153 
154  for (int n = 0; n < interp_comp; n++)
155  interp_vals[n] = sx_lo[0]*sx_lo[1]*sx_lo[2]*interp_array(i-1, j-1, k-1,n) +
156  sx_lo[0]*sx_lo[1]*sx_hi[2]*interp_array(i-1, j-1, k ,n) +
157  sx_lo[0]*sx_hi[1]*sx_lo[2]*interp_array(i-1, j , k-1,n) +
158  sx_lo[0]*sx_hi[1]*sx_hi[2]*interp_array(i-1, j , k ,n) +
159  sx_hi[0]*sx_lo[1]*sx_lo[2]*interp_array(i , j-1, k-1,n) +
160  sx_hi[0]*sx_lo[1]*sx_hi[2]*interp_array(i , j-1, k ,n) +
161  sx_hi[0]*sx_hi[1]*sx_lo[2]*interp_array(i , j , k-1,n) +
162  sx_hi[0]*sx_hi[1]*sx_hi[2]*interp_array(i , j , k ,n);
163  }

Referenced by compute_plane_averages(), and compute_region_averages().

Here is the caller graph for this function:

◆ update_field_ptrs()

void MOSTAverage::update_field_ptrs ( int  lev,
amrex::Vector< amrex::Vector< amrex::MultiFab >> &  vars_old,
amrex::Vector< std::unique_ptr< amrex::MultiFab >> &  Theta_prim,
amrex::Vector< std::unique_ptr< amrex::MultiFab >> &  Qv_prim,
amrex::Vector< std::unique_ptr< amrex::MultiFab >> &  Qr_prim 
)

Function to reset the pointers to field variables.

Parameters
[in]levCurrent level
[in]vars_oldConserved variables at each level
[in]Theta_primPrimitive theta component at each level
233 {
234  m_fields[lev][0] = &vars_old[lev][Vars::xvel];
235  m_fields[lev][1] = &vars_old[lev][Vars::yvel];
236  m_fields[lev][2] = Theta_prim[lev].get();
237  m_fields[lev][3] = Qv_prim[lev].get();
238  m_fields[lev][4] = Qr_prim[lev].get();
239  m_fields[lev][5] = &vars_old[lev][Vars::zvel];
240 }
@ xvel
Definition: ERF_IndexDefines.H:130
@ zvel
Definition: ERF_IndexDefines.H:132
@ yvel
Definition: ERF_IndexDefines.H:131

Referenced by ABLMost::update_mac_ptrs().

Here is the caller graph for this function:

◆ write_averages()

void MOSTAverage::write_averages ( int  lev)

Function to write averages to text file.

Parameters
[in]levCurrent level
1432 {
1433  // Peel back the level
1434  auto& averages = m_averages[lev];
1435 
1436  int navg = m_navg - 1;
1437 
1438  std::ofstream ofile;
1439  ofile.open ("MOST_averages.txt");
1440  ofile << "Averages computed via MOSTAverages class:\n";
1441 
1442  for (MFIter mfi(*averages[navg], TileNoZ()); mfi.isValid(); ++mfi) {
1443  Box bx = mfi.tilebox(); bx.setBig(2,0);
1444  int il = bx.smallEnd(0); int iu = bx.bigEnd(0);
1445  int jl = bx.smallEnd(1); int ju = bx.bigEnd(1);
1446 
1447  for (int j(jl); j <= ju; ++j) {
1448  for (int i(il); i <= iu; ++i) {
1449  ofile << "(I,J): " << "(" << i << "," << j << ")" << "\n";
1450  int k = 0;
1451  for (int iavg(0); iavg <= navg; ++iavg) {
1452  auto mf_arr = averages[iavg]->array(mfi);
1453  ofile << "iavg val: "
1454  << iavg << ' '
1455  << mf_arr(i,j,k) << "\n";
1456  }
1457  ofile << "\n";
1458  }
1459  }
1460  }
1461  ofile.close();
1462 }
Here is the call graph for this function:

◆ write_k_indices()

void MOSTAverage::write_k_indices ( int  lev)

Function to write the K indices to text file.

Parameters
[in]levCurrent level
1314 {
1315  // Peel back the level
1316  auto& averages = m_averages[lev];
1317  auto& k_indx = m_k_indx[lev];
1318 
1319  int navg = m_navg - 1;
1320 
1321  std::ofstream ofile;
1322  ofile.open ("MOST_k_indices.txt");
1323  ofile << "K indices used to compute averages via MOSTAverages class:\n";
1324 
1325  for (MFIter mfi(*averages[navg], TileNoZ()); mfi.isValid(); ++mfi) {
1326  Box bx = mfi.tilebox(); bx.setBig(2,0);
1327  int il = bx.smallEnd(0); int iu = bx.bigEnd(0);
1328  int jl = bx.smallEnd(1); int ju = bx.bigEnd(1);
1329 
1330  auto k_arr = k_indx->array(mfi);
1331 
1332  for (int j(jl); j <= ju; ++j) {
1333  for (int i(il); i <= iu; ++i) {
1334  ofile << "(I,J): " << "(" << i << "," << j << ")" << "\n";
1335  int k = 0;
1336  ofile << "K_ind: "
1337  << k_arr(i,j,k) << "\n";
1338  ofile << "\n";
1339  }
1340  }
1341  }
1342  ofile.close();
1343 }
Here is the call graph for this function:

◆ write_norm_indices()

void MOSTAverage::write_norm_indices ( int  lev)

Function to write I,J,K indices to text file.

Parameters
[in]levCurrent level
1353 {
1354  // Peel back the level
1355  auto& averages = m_averages[lev];
1356  auto& k_indx = m_k_indx[lev];
1357  auto& j_indx = m_j_indx[lev];
1358  auto& i_indx = m_i_indx[lev];
1359 
1360  int navg = m_navg - 1;
1361 
1362  std::ofstream ofile;
1363  ofile.open ("MOST_ijk_indices.txt");
1364  ofile << "IJK indices used to compute averages via MOSTAverages class:\n";
1365 
1366  for (MFIter mfi(*averages[navg], TileNoZ()); mfi.isValid(); ++mfi) {
1367  Box bx = mfi.tilebox(); bx.setBig(2,0);
1368  int il = bx.smallEnd(0); int iu = bx.bigEnd(0);
1369  int jl = bx.smallEnd(1); int ju = bx.bigEnd(1);
1370 
1371  auto k_arr = k_indx->array(mfi);
1372  auto j_arr = j_indx ? j_indx->array(mfi) : Array4<int> {};
1373  auto i_arr = i_indx ? i_indx->array(mfi) : Array4<int> {};
1374 
1375  for (int j(jl); j <= ju; ++j) {
1376  for (int i(il); i <= iu; ++i) {
1377  ofile << "(I1,J1,K1): " << "(" << i << "," << j << "," << 0 << ")" << "\n";
1378 
1379  int k = 0;
1380  int km = k_arr(i,j,k);
1381  int jm = j_arr ? j_arr(i,j,k) : j;
1382  int im = i_arr ? i_arr(i,j,k) : i;
1383 
1384  ofile << "(I2,J2,K2): "
1385  << "(" << im << "," << jm << "," << km << ")" << "\n";
1386  ofile << "\n";
1387  }
1388  }
1389  }
1390  ofile.close();
1391 }
Here is the call graph for this function:

◆ write_xz_positions()

void MOSTAverage::write_xz_positions ( int  lev,
int  j 
)

Function to write X & Z positions to text file.

Parameters
[in]levCurrent level
[in]jIndex in y-dir
1402 {
1403  // Peel back the level
1404  auto& x_pos_mf = m_x_pos[lev];
1405  auto& z_pos_mf = m_z_pos[lev];
1406 
1407  std::ofstream ofile;
1408  ofile.open ("MOST_xz_positions.txt");
1409 
1410  for (MFIter mfi(*x_pos_mf, TileNoZ()); mfi.isValid(); ++mfi) {
1411  Box bx = mfi.tilebox(); bx.setBig(2,0);
1412  int il = bx.smallEnd(0); int iu = bx.bigEnd(0);
1413 
1414  auto x_pos_arr = x_pos_mf->array(mfi);
1415  auto z_pos_arr = z_pos_mf->array(mfi);
1416 
1417  int k = 0;
1418  for (int i(il); i <= iu; ++i)
1419  ofile << x_pos_arr(i,j,k) << ' ' << z_pos_arr(i,j,k) << "\n";
1420  }
1421  ofile.close();
1422 }
Here is the call graph for this function:

Member Data Documentation

◆ include_subgrid_vel

bool MOSTAverage::include_subgrid_vel = false
protected

◆ m_averages

amrex::Vector<amrex::Vector<std::unique_ptr<amrex::MultiFab> > > MOSTAverage::m_averages
protected

◆ m_fact_new

amrex::Real MOSTAverage::m_fact_new
protected

◆ m_fact_old

amrex::Real MOSTAverage::m_fact_old
protected

◆ m_fields

amrex::Vector<amrex::Vector<amrex::MultiFab*> > MOSTAverage::m_fields
protected

◆ m_geom

◆ m_i_indx

amrex::Vector<std::unique_ptr<amrex::iMultiFab> > MOSTAverage::m_i_indx
protected

◆ m_interp

bool MOSTAverage::m_interp {false}
protected

◆ m_j_indx

amrex::Vector<std::unique_ptr<amrex::iMultiFab> > MOSTAverage::m_j_indx
protected

◆ m_k_in

amrex::Vector<int> MOSTAverage::m_k_in
protected

Referenced by set_k_indices_N(), and set_k_indices_T().

◆ m_k_indx

amrex::Vector<std::unique_ptr<amrex::iMultiFab> > MOSTAverage::m_k_indx
protected

◆ m_maxlev

◆ m_navg

◆ m_ncell_plane

amrex::Vector<amrex::Vector<int> > MOSTAverage::m_ncell_plane
protected

◆ m_ncell_region

int MOSTAverage::m_ncell_region {1}
protected

◆ m_norm_vec

bool MOSTAverage::m_norm_vec {false}
protected

◆ m_nvar

int MOSTAverage::m_nvar {6}
protected

◆ m_plane_average

amrex::Vector<amrex::Vector<amrex::Real> > MOSTAverage::m_plane_average
protected

◆ m_policy

int MOSTAverage::m_policy {0}
protected

Referenced by compute_averages().

◆ m_pp_prefix

std::string MOSTAverage::m_pp_prefix {"erf"}
protected

◆ m_radius

◆ m_rot_fields

amrex::Vector<amrex::Vector<std::unique_ptr<amrex::MultiFab> > > MOSTAverage::m_rot_fields
protected

◆ m_rotate

bool MOSTAverage::m_rotate {false}
protected

◆ m_t_avg

bool MOSTAverage::m_t_avg {false}
protected

◆ m_t_init

amrex::Vector<int> MOSTAverage::m_t_init
protected

◆ m_time_window

amrex::Real MOSTAverage::m_time_window {1.0e-16}
protected

◆ m_Vsg

amrex::Vector<amrex::Real> MOSTAverage::m_Vsg
protected

◆ m_x_pos

amrex::Vector<std::unique_ptr<amrex::MultiFab> > MOSTAverage::m_x_pos
protected

◆ m_y_pos

amrex::Vector<std::unique_ptr<amrex::MultiFab> > MOSTAverage::m_y_pos
protected

◆ m_z_phys_nd

amrex::Vector<amrex::MultiFab*> MOSTAverage::m_z_phys_nd
protected

◆ m_z_pos

amrex::Vector<std::unique_ptr<amrex::MultiFab> > MOSTAverage::m_z_pos
protected

◆ m_zref

amrex::Real MOSTAverage::m_zref {10.0}
protected

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