Skip to content

Commit da0b0ef

Browse files
committed
Quartic interpolation for cell centered data
New Interpolator for interpolation of cell centered data using a fourth-degreee polynomial. Note that the interpolation is not conservative and does not do any slope limiting.
1 parent 3e5cc77 commit da0b0ef

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed

Src/AmrCore/AMReX_Interp_C.H

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,53 @@ face_linear_interp_z (int i, int j, int k, int n, amrex::Array4<amrex::Real> con
135135
}
136136
}
137137

138+
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
139+
void cell_quartic_interp_x (int i, int j, int k, int n, Array4<Real> const& fine,
140+
Array4<Real const> const& crse) noexcept
141+
{
142+
constexpr Array1D<Real,-2,2> c = {Real(0.01708984), Real(-0.12304688),
143+
Real(0.92285156), Real(0.20507812),
144+
Real(-0.02197266)};
145+
int ii = amrex::coarsen(i,2);
146+
int s = 2*(i-ii*2) - 1; // if i == ii*2, s = -1; if i == ii*2+1, s = 1;
147+
fine(i,j,k,n) = c[-2*s]*crse(ii-2,j,k,n)
148+
+ c[ -s]*crse(ii-1,j,k,n)
149+
+ c[ 0]*crse(ii ,j,k,n)
150+
+ c[ s]*crse(ii+1,j,k,n)
151+
+ c[ 2*s]*crse(ii+2,j,k,n);
152+
}
153+
154+
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
155+
void cell_quartic_interp_y (int i, int j, int k, int n, Array4<Real> const& fine,
156+
Array4<Real const> const& crse) noexcept
157+
{
158+
constexpr Array1D<Real,-2,2> c = {Real(0.01708984), Real(-0.12304688),
159+
Real(0.92285156), Real(0.20507812),
160+
Real(-0.02197266)};
161+
int jj = amrex::coarsen(j,2);
162+
int s = 2*(j-jj*2) - 1; // if j == jj*2, s = -1; if j == jj*2+1, s = 1;
163+
fine(i,j,k,n) = c[-2*s]*crse(i,jj-2,k,n)
164+
+ c[ -s]*crse(i,jj-1,k,n)
165+
+ c[ 0]*crse(i,jj ,k,n)
166+
+ c[ s]*crse(i,jj+1,k,n)
167+
+ c[ 2*s]*crse(i,jj+2,k,n);
168+
}
169+
170+
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
171+
void cell_quartic_interp_z (int i, int j, int k, int n, Array4<Real> const& fine,
172+
Array4<Real const> const& crse) noexcept
173+
{
174+
constexpr Array1D<Real,-2,2> c = {Real(0.01708984), Real(-0.12304688),
175+
Real(0.92285156), Real(0.20507812),
176+
Real(-0.02197266)};
177+
int kk = amrex::coarsen(k,2);
178+
int s = 2*(k-kk*2) - 1; // if k == kk*2, s = -1; if k == kk*2+1, s = 1;
179+
fine(i,j,k,n) = c[-2*s]*crse(i,j,kk-2,n)
180+
+ c[ -s]*crse(i,j,kk-1,n)
181+
+ c[ 0]*crse(i,j,kk ,n)
182+
+ c[ s]*crse(i,j,kk+1,n)
183+
+ c[ 2*s]*crse(i,j,kk+2,n);
184+
}
185+
138186
}
139187
#endif

Src/AmrCore/AMReX_Interpolater.H

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,74 @@ public:
844844

845845
};
846846

847+
/**
848+
* \brief Quartic interpolation on cell centered data.
849+
*
850+
* Quartic interpolation on cell centered data.
851+
*/
852+
853+
class CellQuartic
854+
:
855+
public Interpolater
856+
{
857+
public:
858+
859+
/**
860+
* \brief The constructor.
861+
*/
862+
explicit CellQuartic ();
863+
864+
/**
865+
* \brief The destructor.
866+
*/
867+
virtual ~CellQuartic () override;
868+
869+
/**
870+
* \brief Returns coarsened box given fine box and refinement ratio.
871+
*
872+
* \param fine
873+
* \param ratio
874+
*/
875+
virtual Box CoarseBox (const Box& fine, int ratio) override;
876+
877+
/**
878+
* \brief Returns coarsened box given fine box and refinement ratio.
879+
*
880+
* \param fine
881+
* \param ratio
882+
*/
883+
virtual Box CoarseBox (const Box& fine, const IntVect& ratio) override;
884+
885+
/**
886+
* \brief Coarse to fine interpolation in space.
887+
*
888+
* \param crse
889+
* \param crse_comp
890+
* \param fine
891+
* \param fine_comp
892+
* \param ncomp
893+
* \param fine_region
894+
* \param ratio
895+
* \param crse_geom
896+
* \param fine_geom
897+
* \param bcr
898+
* \param actual_comp
899+
* \param actual_state
900+
*/
901+
virtual void interp (const FArrayBox& crse,
902+
int crse_comp,
903+
FArrayBox& fine,
904+
int fine_comp,
905+
int ncomp,
906+
const Box& fine_region,
907+
const IntVect& ratio,
908+
const Geometry& crse_geom,
909+
const Geometry& fine_geom,
910+
Vector<BCRec> const& bcr,
911+
int actual_comp,
912+
int actual_state,
913+
RunOn gpu_or_cpu) override;
914+
};
847915

848916
//! CONSTRUCT A GLOBAL OBJECT OF EACH VERSION.
849917
extern AMREX_EXPORT PCInterp pc_interp;
@@ -856,6 +924,7 @@ extern AMREX_EXPORT CellBilinear cell_bilinear_interp;
856924
extern AMREX_EXPORT CellConservativeProtected protected_interp;
857925
extern AMREX_EXPORT CellConservativeQuartic quartic_interp;
858926
extern AMREX_EXPORT CellQuadratic quadratic_interp;
927+
extern AMREX_EXPORT CellQuartic cell_quartic_interp;
859928

860929
}
861930

Src/AmrCore/AMReX_Interpolater.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ namespace amrex {
1818
*
1919
* CellQuadratic only works in 2D and 3D on cpu and gpu.
2020
*
21+
* CellQuartic works in 1D, 2D and 3D on cpu and gpu with ref ratio of 2
22+
*
2123
* CellConservativeQuartic only works with ref ratio of 2 on cpu and gpu.
2224
*
2325
* FaceDivFree works in 2D and 3D on cpu and gpu.
@@ -37,6 +39,7 @@ CellConservativeProtected protected_interp;
3739
CellConservativeQuartic quartic_interp;
3840
CellBilinear cell_bilinear_interp;
3941
CellQuadratic quadratic_interp;
42+
CellQuartic cell_quartic_interp;
4043

4144
NodeBilinear::~NodeBilinear () {}
4245

@@ -988,4 +991,91 @@ FaceDivFree::interp_arr (Array<FArrayBox*, AMREX_SPACEDIM> const& crse,
988991
});
989992
}
990993

994+
CellQuartic::CellQuartic () {}
995+
996+
CellQuartic::~CellQuartic () {}
997+
998+
Box
999+
CellQuartic::CoarseBox (const Box& fine, const IntVect& ratio)
1000+
{
1001+
Box crse = amrex::coarsen(fine,ratio);
1002+
crse.grow(2);
1003+
return crse;
1004+
}
1005+
1006+
Box
1007+
CellQuartic::CoarseBox (const Box& fine, int ratio)
1008+
{
1009+
Box crse = amrex::coarsen(fine,ratio);
1010+
crse.grow(2);
1011+
return crse;
1012+
}
1013+
1014+
void
1015+
CellQuartic::interp (const FArrayBox& crse,
1016+
int crse_comp,
1017+
FArrayBox& fine,
1018+
int fine_comp,
1019+
int ncomp,
1020+
const Box& fine_region,
1021+
const IntVect& ratio,
1022+
const Geometry& /*crse_geom*/,
1023+
const Geometry& /*fine_geom*/,
1024+
Vector<BCRec> const& /*bcr*/,
1025+
int /* actual_comp */,
1026+
int /* actual_state */,
1027+
RunOn runon)
1028+
{
1029+
BL_PROFILE("CellQuartic::interp()");
1030+
amrex::ignore_unused(ratio);
1031+
AMREX_ASSERT(ratio == 2);
1032+
1033+
Box target_fine_region = fine_region & fine.box();
1034+
1035+
bool run_on_gpu = (runon == RunOn::Gpu && Gpu::inLaunchRegion());
1036+
1037+
Array4<Real const> const& crsearr = crse.const_array(crse_comp);
1038+
Array4<Real> const& finearr = fine.array(fine_comp);
1039+
1040+
#if (AMREX_SPACEDIM == 3)
1041+
Box bz = amrex::coarsen(target_fine_region, IntVect(2,2,1));
1042+
bz.grow(IntVect(2,2,0));
1043+
FArrayBox tmpz(bz, ncomp);
1044+
Elixir tmpz_eli = tmpz.elixir();
1045+
Array4<Real> const& tmpzarr = tmpz.array();
1046+
AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(runon, bz, ncomp, i, j, k, n,
1047+
{
1048+
cell_quartic_interp_z(i,j,k,n,tmpzarr,crsearr);
1049+
});
1050+
#endif
1051+
1052+
#if (AMREX_SPACEDIM >= 2)
1053+
Box by = amrex::coarsen(target_fine_region, IntVect(AMREX_D_DECL(2,1,1)));
1054+
by.grow(IntVect(AMREX_D_DECL(2,0,0)));
1055+
FArrayBox tmpy(by, ncomp);
1056+
Elixir tmpy_eli = tmpy.elixir();
1057+
Array4<Real> const& tmpyarr = tmpy.array();
1058+
#if (AMREX_SPACEDIM == 2)
1059+
Array4<Real const> srcarr = crsearr;
1060+
#else
1061+
Array4<Real const> srcarr = tmpz.const_array();
1062+
#endif
1063+
AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(runon, by, ncomp, i, j, k, n,
1064+
{
1065+
cell_quartic_interp_y(i,j,k,n,tmpyarr,srcarr);
1066+
});
1067+
#endif
1068+
1069+
#if (AMREX_SPACEDIM == 1)
1070+
Array4<Real const> srcarr = crsearr;
1071+
#else
1072+
srcarr = tmpy.const_array();
1073+
#endif
1074+
AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(runon, target_fine_region, ncomp,
1075+
i, j, k, n,
1076+
{
1077+
cell_quartic_interp_x(i,j,k,n,finearr,srcarr);
1078+
});
1079+
}
1080+
9911081
}

0 commit comments

Comments
 (0)