aboutsummaryrefslogtreecommitdiff
path: root/Carpet/CarpetLib/src/interpolate_3d_3tl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Carpet/CarpetLib/src/interpolate_3d_3tl.cc')
-rw-r--r--Carpet/CarpetLib/src/interpolate_3d_3tl.cc208
1 files changed, 208 insertions, 0 deletions
diff --git a/Carpet/CarpetLib/src/interpolate_3d_3tl.cc b/Carpet/CarpetLib/src/interpolate_3d_3tl.cc
new file mode 100644
index 000000000..04d0e1e94
--- /dev/null
+++ b/Carpet/CarpetLib/src/interpolate_3d_3tl.cc
@@ -0,0 +1,208 @@
+#include <algorithm>
+#include <cassert>
+#include <cmath>
+#include <cstdlib>
+
+#include <cctk.h>
+#include <cctk_Parameters.h>
+
+#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 <typename T>
+ 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<T>::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<regkext; ++k) {
+ for (size_t j=0; j<regjext; ++j) {
+ for (size_t i=0; i<regiext; ++i) {
+
+ dst [DSTIND3(i, j, k)] =
+ + s1fac * src1 [SRCIND3(i, j, k)]
+ + s2fac * src2 [SRCIND3(i, j, k)]
+ + s3fac * src3 [SRCIND3(i, j, k)];
+
+ }
+ }
+ }
+
+ }
+
+
+
+ template
+ void
+ interpolate_3d_3tl (CCTK_REAL const * restrict const src1,
+ CCTK_REAL const t1,
+ CCTK_REAL const * restrict const src2,
+ CCTK_REAL const t2,
+ CCTK_REAL const * restrict const src3,
+ CCTK_REAL const t3,
+ ivect3 const & srcext,
+ CCTK_REAL * restrict const dst,
+ CCTK_REAL const t,
+ ivect3 const & dstext,
+ ibbox3 const & srcbbox,
+ ibbox3 const & dstbbox,
+ ibbox3 const & regbbox);
+
+ template
+ void
+ interpolate_3d_3tl (CCTK_COMPLEX const * restrict const src1,
+ CCTK_REAL const t1,
+ CCTK_COMPLEX const * restrict const src2,
+ CCTK_REAL const t2,
+ CCTK_COMPLEX const * restrict const src3,
+ CCTK_REAL const t3,
+ ivect3 const & srcext,
+ CCTK_COMPLEX * restrict const dst,
+ CCTK_REAL const t,
+ ivect3 const & dstext,
+ ibbox3 const & srcbbox,
+ ibbox3 const & dstbbox,
+ ibbox3 const & regbbox);
+
+
+
+} // namespace CarpetLib