#include #include #include #include #include #include #include "operator_prototypes.hh" #include "typeprops.hh" using namespace std; namespace CarpetLib { #define SRCIND3(i,j,k) \ index3 (srcioff + (i), srcjoff + (j), srckoff + (k), \ srciext, srcjext, srckext) #define DSTIND3(i,j,k) \ index3 (dstioff + (i), dstjoff + (j), dstkoff + (k), \ dstiext, dstjext, dstkext) template void interpolate_3d_3tl (T const * restrict const src1, CCTK_REAL const t1, T const * restrict const src2, CCTK_REAL const t2, T const * restrict const src3, CCTK_REAL const t3, ivect3 const & srcext, T * restrict const dst, CCTK_REAL const t, ivect3 const & dstext, ibbox3 const & srcbbox, ibbox3 const & dstbbox, ibbox3 const & regbbox) { typedef typename typeprops::real RT; #if 0 // This is already guaranteed by bbox if (any (srcbbox.stride() == 0 or dstbbox.stride() == 0 or regbbox.stride() == 0)) { CCTK_WARN (0, "Internal error: stride is zero"); } #endif if (any (srcbbox.stride() != regbbox.stride() or dstbbox.stride() != regbbox.stride())) { CCTK_WARN (0, "Internal error: strides disagree"); } if (any (srcbbox.stride() != dstbbox.stride())) { CCTK_WARN (0, "Internal error: strides disagree"); } #if 0 // This needs to be allowed for cell centring if (any (srcbbox.lower() % srcbbox.stride() != 0 or dstbbox.lower() % dstbbox.stride() != 0 or regbbox.lower() % regbbox.stride() != 0)) { CCTK_WARN (0, "Internal error: array origins are not integer multiples of the strides"); } #endif // This could be handled, but is likely to point to an error // elsewhere if (regbbox.empty()) { CCTK_WARN (0, "Internal error: region extent is empty"); } #if 0 // This is already guaranteed by bbox if (any ((srcbbox.upper() - srcbbox.lower()) % srcbbox.stride() != 0 or (dstbbox.upper() - dstbbox.lower()) % dstbbox.stride() != 0 or (regbbox.upper() - regbbox.lower()) % regbbox.stride() != 0)) { CCTK_WARN (0, "Internal error: array extents are not integer multiples of the strides"); } #endif if (not regbbox.is_contained_in(srcbbox) or not regbbox.is_contained_in(dstbbox)) { CCTK_WARN (0, "Internal error: region extent is not contained in array extent"); } if (any (srcext != srcbbox.shape() / srcbbox.stride() or dstext != dstbbox.shape() / dstbbox.stride())) { CCTK_WARN (0, "Internal error: array sizes don't agree with bounding boxes"); } ivect3 const regext = regbbox.shape() / regbbox.stride(); assert (all ((regbbox.lower() - srcbbox.lower()) % srcbbox.stride() == 0)); ivect3 const srcoff = (regbbox.lower() - srcbbox.lower()) / srcbbox.stride(); assert (all ((regbbox.lower() - dstbbox.lower()) % dstbbox.stride() == 0)); ivect3 const dstoff = (regbbox.lower() - dstbbox.lower()) / dstbbox.stride(); size_t const srciext = srcext[0]; size_t const srcjext = srcext[1]; size_t const srckext = srcext[2]; size_t const dstiext = dstext[0]; size_t const dstjext = dstext[1]; size_t const dstkext = dstext[2]; size_t const regiext = regext[0]; size_t const regjext = regext[1]; size_t const regkext = regext[2]; size_t const srcioff = srcoff[0]; size_t const srcjoff = srcoff[1]; size_t const srckoff = srcoff[2]; size_t const dstioff = dstoff[0]; size_t const dstjoff = dstoff[1]; size_t const dstkoff = dstoff[2]; // Quadratic (second order) interpolation RT const eps = 1.0e-10; if (abs (t1 - t2) < eps or abs (t1 - t3) < eps or abs (t2 - t3) < eps) { CCTK_WARN (0, "Internal error: arrays have same time"); } if (t < min (min (t1, t2), t3) - eps or t > max (max (t1, t2), t3) + eps) { CCTK_WARN (0, "Internal error: extrapolation in time"); } RT const s1fac = (t - t2) * (t - t3) / ((t1 - t2) * (t1 - t3)); RT const s2fac = (t - t1) * (t - t3) / ((t2 - t1) * (t2 - t3)); RT const s3fac = (t - t1) * (t - t2) / ((t3 - t1) * (t3 - t2)); // Loop over region for (size_t k=0; k