// See also Hern, "Numerical Relativity and Inhomogeneous // Cosmologies", gr-qc/0004036, section 3.2, pp. 29 ff.; especially // the last equation on page 37. #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) // Convert from the "standard" form of the grid function to the // "primitive" version, i.e., the antiderivative template void prolongate_3d_cc_rf2_std2prim (T const * restrict const src, ivect3 const & restrict srcext, T * restrict const dst, ivect3 const & restrict dstext, ibbox3 const & restrict srcbbox, ibbox3 const & restrict dstbbox, ibbox3 const & restrict regbbox) { DECLARE_CCTK_PARAMETERS; typedef typename typeprops::real RT; T (* const fromreal) (RT) = typeprops::fromreal; 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"); } // 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 (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.stride() % 2 == 0)); assert (all ((regbbox.lower() - srcbbox.lower() + regbbox.stride() / 2) % regbbox.stride() == 0)); ivect3 const srcoff = (regbbox.lower() - srcbbox.lower() + regbbox.stride() / 2) / regbbox.stride(); assert (all ((regbbox.lower() - dstbbox.lower()) % regbbox.stride() == 0)); ivect3 const dstoff = (regbbox.lower() - dstbbox.lower()) / regbbox.stride(); int const srciext = srcext[0]; int const srcjext = srcext[1]; int const srckext = srcext[2]; int const dstiext = dstext[0]; int const dstjext = dstext[1]; int const dstkext = dstext[2]; int const regiext = regext[0]; int const regjext = regext[1]; int const regkext = regext[2]; int const srcioff = srcoff[0]; int const srcjoff = srcoff[1]; int const srckoff = srcoff[2]; int const dstioff = dstoff[0]; int const dstjoff = dstoff[1]; int const dstkoff = dstoff[2]; T const zero = fromreal (0); #pragma omp parallel for for (int k=0; k void prolongate_3d_cc_rf2_prim2std (T const * restrict const src, ivect const & restrict srcext, T * restrict const dst, ivect const & restrict dstext, ibbox3 const & restrict srcbbox, ibbox3 const & restrict dstbbox, ibbox3 const & restrict regbbox) { DECLARE_CCTK_PARAMETERS; 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"); } // 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 (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.stride() % 2 == 0)); assert (all ((regbbox.lower() - srcbbox.lower() - regbbox.stride() / 2) % regbbox.stride() == 0)); ivect3 const srcoff = (regbbox.lower() - srcbbox.lower() - regbbox.stride() / 2) / regbbox.stride(); assert (all ((regbbox.lower() - dstbbox.lower()) % regbbox.stride() == 0)); ivect3 const dstoff = (regbbox.lower() - dstbbox.lower()) / regbbox.stride(); int const srciext = srcext[0]; int const srcjext = srcext[1]; int const srckext = srcext[2]; int const dstiext = dstext[0]; int const dstjext = dstext[1]; int const dstkext = dstext[2]; int const regiext = regext[0]; int const regjext = regext[1]; int const regkext = regext[2]; int const srcioff = srcoff[0]; int const srcjoff = srcoff[1]; int const srckoff = srcoff[2]; int const dstioff = dstoff[0]; int const dstjoff = dstoff[1]; int const dstkoff = dstoff[2]; #pragma omp parallel for for (int k=0; k