/home/runner/work/kynema-sgf/kynema-sgf/src/utilities/index_operations.H Source File

Kynema-SGF API: /home/runner/work/kynema-sgf/kynema-sgf/src/utilities/index_operations.H Source File
Kynema-SGF API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
index_operations.H
Go to the documentation of this file.
1#ifndef INDEX_OPERATIONS_H
2#define INDEX_OPERATIONS_H
3#include <algorithm>
4
5#include "AMReX_REAL.H"
6#include "AMReX_Vector.H"
7#include "AMReX_Box.H"
8#include "AMReX_RealBox.H"
9#include "AMReX_RealVect.H"
10#include "AMReX_Geometry.H"
11#include "AMReX_Array4.H"
12#include "AMReX_Gpu.H"
13#include "AMReX_Orientation.H"
14#include "AMReX_MultiFab.H"
15#include "AMReX_BCRec.H"
16
17using namespace amrex::literals;
18
19namespace kynema_sgf::utils {
20
22AMREX_FORCE_INLINE int closest_index(
23 const amrex::Vector<amrex::Real>& vec,
24 const amrex::Real value,
25 const amrex::Real tol = 0.0_rt)
26{
27 auto it = std::ranges::upper_bound(vec, value);
28 if (it == vec.end()) {
29 // Try again with tolerance added
30 it = std::ranges::upper_bound(vec, value - tol);
31 }
32 AMREX_ALWAYS_ASSERT(it != vec.end());
33
34 const int idx = static_cast<int>(std::distance(vec.begin(), it));
35 return amrex::max(idx - 1, 0);
36}
37
39template <typename T = amrex::GpuArray<int, 2>>
40AMREX_FORCE_INLINE T perpendicular_idx(const int normal)
41{
42 switch (normal) {
43 case 0:
44 return T{1, 2};
45 case 1:
46 return T{0, 2};
47 case 2:
48 return T{0, 1};
49 default:
50 amrex::Abort("Invalid normal value to determine perpendicular indices");
51 }
52 return T{-1, -1};
53}
54
69 amrex::IntVect& shift_to_cc,
70 amrex::Box grown_interior_box,
71 const amrex::Box& domain_boundary_box,
72 const amrex::Orientation& ori)
73{
74 shift_to_cc = {0, 0, 0};
75 const auto& field_location_vector = grown_interior_box.type();
76 if (!grown_interior_box.cellCentered()) {
77 grown_interior_box.enclosedCells();
78 }
79 auto bx = grown_interior_box & domain_boundary_box;
80 if (bx.isEmpty()) {
81 return bx;
82 }
83
84 if (ori.isHigh() && field_location_vector[ori.coordDir()] == 1) {
85 bx.shift(field_location_vector);
86 shift_to_cc = -field_location_vector;
87 }
88 return bx;
89}
90
91// This version omits the shift to cell-centered data, often not needed
93 amrex::Box grown_interior_box,
94 const amrex::Box& domain_boundary_box,
95 const amrex::Orientation& ori)
96{
97 amrex::IntVect shift_to_cc = {0, 0, 0};
99 shift_to_cc, grown_interior_box, domain_boundary_box, ori);
100}
101
117 const amrex::Box& bx,
118 amrex::Array4<amrex::Real> const& arr,
119 const amrex::Orientation& ori,
120 const int scomp,
121 const int ncomp)
122{
123 if (!bx.ok()) {
124 return;
125 }
126 const int idir = ori.coordDir();
127 AMREX_ASSERT(bx.length(idir) == 1);
128 const amrex::IntVect arr_lo(amrex::lbound(arr));
129 const amrex::IntVect arr_hi(amrex::ubound(arr));
130 const int nlayers = ori.isLow() ? (bx.smallEnd(idir) - arr_lo[idir])
131 : (arr_hi[idir] - bx.bigEnd(idir));
132 if (nlayers <= 0) {
133 return;
134 }
135 const amrex::IntVect outward =
136 amrex::IntVect::TheDimensionVector(idir) * (ori.isLow() ? -1 : 1);
137 amrex::ParallelFor(
138 bx, ncomp, [=] AMREX_GPU_DEVICE(int i, int j, int k, int n) {
139 const amrex::IntVect iv{i, j, k};
140 for (int g = 1; g <= nlayers; ++g) {
141 arr(iv + (g * outward), scomp + n) = arr(iv, scomp + n);
142 }
143 });
144}
145
154 amrex::MultiFab& mfab,
155 const amrex::Geometry& geom,
156 const amrex::Vector<amrex::BCRec>& bcrec,
157 amrex::Orientation ori,
158 int dcomp,
159 int ncomp,
160 int orig_comp = 0);
161
165amrex::FArrayBox interpolate_boundary_plane(
166 const amrex::FArrayBox& coarse,
167 const amrex::FArrayBox& fine,
168 amrex::Orientation ori,
169 amrex::IntVect ratio,
170 const amrex::Geometry& coarse_geom,
171 const amrex::Geometry& fine_geom,
172 int nghost);
173
175AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool contains(
176 const amrex::Box& box,
177 const amrex::RealVect& pos,
178 const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& prob_lo,
179 const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dxinv)
180{
181 const amrex::IntVect iv(AMREX_D_DECL(
182 static_cast<int>(amrex::Math::floor((pos[0] - prob_lo[0]) * dxinv[0])),
183 static_cast<int>(amrex::Math::floor((pos[1] - prob_lo[1]) * dxinv[1])),
184 static_cast<int>(
185 amrex::Math::floor((pos[2] - prob_lo[2]) * dxinv[2]))));
186 return box.contains(iv);
187}
188
196amrex::Box
197realbox_to_box(const amrex::RealBox& rbx, const amrex::Geometry& geom);
198
199} // namespace kynema_sgf::utils
200
201#endif /* INDEX_OPERATIONS_H */
Definition MultiParser.H:7
void fill_transverse_ghosts(amrex::MultiFab &mfab, const amrex::Geometry &geom, const amrex::Vector< amrex::BCRec > &bcrec, const amrex::Orientation ori, const int dcomp, const int ncomp, const int orig_comp)
Definition ghost_fill.cpp:144
AMREX_INLINE amrex::Box face_aware_boundary_box_intersection(amrex::IntVect &shift_to_cc, amrex::Box grown_interior_box, const amrex::Box &domain_boundary_box, const amrex::Orientation &ori)
Definition index_operations.H:68
AMREX_FORCE_INLINE int closest_index(const amrex::Vector< amrex::Real > &vec, const amrex::Real value, const amrex::Real tol=0.0_rt)
Return closest index (from lower) of value in vector.
Definition index_operations.H:22
amrex::FArrayBox interpolate_boundary_plane(const amrex::FArrayBox &coarse, const amrex::FArrayBox &fine, const amrex::Orientation ori, amrex::IntVect ratio, const amrex::Geometry &coarse_geom, const amrex::Geometry &fine_geom, const int nghost)
Definition ghost_fill.cpp:9
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool contains(const amrex::Box &box, const amrex::RealVect &pos, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &prob_lo, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dxinv)
Check if a point is inside a box.
Definition index_operations.H:175
amrex::Box realbox_to_box(const amrex::RealBox &rbx, const amrex::Geometry &geom)
Definition index_operations.cpp:5
AMREX_FORCE_INLINE T perpendicular_idx(const int normal)
Return indices perpendicular to normal.
Definition index_operations.H:40
AMREX_INLINE void extend_boundary_ghost_layers(const amrex::Box &bx, amrex::Array4< amrex::Real > const &arr, const amrex::Orientation &ori, const int scomp, const int ncomp)
Definition index_operations.H:116