summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authoreschnett <eschnett@17b73243-c579-4c4c-a9d2-2d5706c11dac>2012-06-18 01:47:05 +0000
committereschnett <eschnett@17b73243-c579-4c4c-a9d2-2d5706c11dac>2012-06-18 01:47:05 +0000
commit47a6b6f908ad8f4607cb8e7830d8159522ce0947 (patch)
treece2900fdc05d4befdc6db7078eff541049f62e9b /src/include
parent84936f9e8bbf8f3e3d04fce50a273ad356b594db (diff)
Add script to auto-generate cctk_Loop.h
Also update API. Add documentation. git-svn-id: http://svn.cactuscode.org/flesh/trunk@4838 17b73243-c579-4c4c-a9d2-2d5706c11dac
Diffstat (limited to 'src/include')
-rw-r--r--src/include/cctk_Loop.h3174
-rwxr-xr-xsrc/include/cctk_Loop.h.pl840
2 files changed, 3509 insertions, 505 deletions
diff --git a/src/include/cctk_Loop.h b/src/include/cctk_Loop.h
index 98c6da6a..aae37034 100644
--- a/src/include/cctk_Loop.h
+++ b/src/include/cctk_Loop.h
@@ -1,542 +1,2706 @@
#ifndef _CCTK_LOOP_H_
#define _CCTK_LOOP_H_
-#include "cctk_Config.h"
+/* WARNING: This file is auto-generated. Do not edit. */
+/* Edit cctk_Loop.h.pl instead, and then re-generate this file via */
+/* perl cctk_Loop.h.pl.pl */
+/* Documentation can also be found in "cctk_Loop.h.pl". */
+
+#ifdef CCODE
+# include <cctk_Config.h>
+# include <cctk_WarnLevel.h>
+# include <cGH.h>
+# include <assert.h>
+#endif /* #ifdef CCODE */
+/* 1D */
+
#ifdef CCODE
-/* C and C++ variants of iterators */
-#include "cctk_WarnLevel.h"
-#include "cGH.h"
+/* LOOP */
+#define CCTK_LOOP1_NORMAL(name, \
+ i, \
+ ni, \
+ idir, \
+ imin, \
+ imax, \
+ ilsh) \
+ CCTK_LOOP1STR_NORMAL(name, \
+ i, \
+ ni, \
+ (idir), \
+ (imin), \
+ (imax), \
+ (ilsh), \
+ 1) \
+#define CCTK_ENDLOOP1_NORMAL(name) \
+ CCTK_ENDLOOP1STR_NORMAL(name) \
-/* 1D */
+#define CCTK_LOOP1STR_NORMAL(name, \
+ i, \
+ ni, \
+ idir, \
+ imin, \
+ imax, \
+ ilsh, \
+ istr) \
+ do { \
+ typedef int cctki0_loop1_normal_##name; \
+ int const cctki0_idir = (idir); \
+ int const cctki0_imin = (imin); \
+ int const cctki0_imax = (imax); \
+ int const cctki0_istr CCTK_ATTRIBUTE_UNUSED = (istr); \
+ assert(cctki0_istr == 1); \
+ _Pragma("omp for") \
+ for (int i=cctki0_imin; i<cctki0_imax; ++i) { \
+ int const ni CCTK_ATTRIBUTE_UNUSED = cctki0_idir<0 ? i+1 : cctki0_idir==0 ? 0 : cctki0_imax-i; \
+ { \
+
+#define CCTK_ENDLOOP1STR_NORMAL(name) \
+ } \
+ } \
+ typedef cctki0_loop1_normal_##name cctki0_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+#define CCTK_LOOP1(name, \
+ i, \
+ imin, \
+ imax, \
+ ilsh) \
+ CCTK_LOOP1STR(name, \
+ i, \
+ (imin), \
+ (imax), \
+ (ilsh), \
+ 1) \
+
+#define CCTK_ENDLOOP1(name) \
+ CCTK_ENDLOOP1STR(name) \
+
+#define CCTK_LOOP1STR(name, \
+ i, \
+ imin, \
+ imax, \
+ ilsh, \
+ istr) \
+ CCTK_LOOP1STR_NORMAL(name, \
+ i, \
+ cctki1_ni, \
+ 0, \
+ imin, \
+ imax, \
+ ilsh, \
+ istr) \
+
+#define CCTK_ENDLOOP1STR(name) \
+ CCTK_ENDLOOP1STR_NORMAL(name) \
+
+
+
+/* LOOP_INTERIOR */
+
+#define CCTK_LOOP1_INTERIOR(name, cctkGH, \
+ i, \
+ iblo, \
+ ibhi) \
+ CCTK_LOOP1STR_INTERIOR(name, (cctkGH), \
+ i, \
+ (iblo), \
+ (ibhi), \
+ 1) \
+
+#define CCTK_ENDLOOP1_INTERIOR(name) \
+ CCTK_ENDLOOP1STR_INTERIOR(name) \
+
+#define CCTK_LOOP1STR_INTERIOR(name, cctkGH, \
+ i, \
+ iblo, \
+ ibhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop1_interior_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 1) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP1_INTERIOR can only be used in 1 dimensions"); \
+ } \
+ CCTK_LOOP1STR(name##_interior, \
+ i, \
+ (iblo), \
+ cctki2_cctkGH->CCTK_LSSH(0,0)-(ibhi), \
+ cctki2_cctkGH->cctk_lsh[0], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP1STR_INTERIOR(name) \
+ } CCTK_ENDLOOP1STR(name##_interior); \
+ typedef cctki2_loop1_interior_##name cctki2_ensure_proper_nesting; \
+ } while(0) \
+
+
+
+/* LOOP_BOUNDARIES */
+
+#define CCTK_LOOP1_BOUNDARIES(name, cctkGH, \
+ i, \
+ ni, \
+ iblo, \
+ ibhi, \
+ ibboxlo, \
+ ibboxhi) \
+ CCTK_LOOP1STR_BOUNDARIES(name, (cctkGH), \
+ i, \
+ ni, \
+ (iblo), \
+ (ibhi), \
+ (ibboxlo), \
+ (ibboxhi), \
+ 1) \
+
+#define CCTK_ENDLOOP1_BOUNDARIES(name) \
+ CCTK_ENDLOOP1STR_BOUNDARIES(name) \
+
+#define CCTK_LOOP1STR_BOUNDARIES(name, cctkGH, \
+ i, \
+ ni, \
+ iblo, \
+ ibhi, \
+ ibboxlo, \
+ ibboxhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop1_boundaries_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 1) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP1_BOUNDARIES can only be used in 1 dimensions"); \
+ } \
+ int const cctki2_blo[] = { (iblo) }; \
+ int const cctki2_bhi[] = { (ibhi) }; \
+ int const cctki2_bbox[] = { (ibboxlo), (ibboxhi) }; \
+ int const cctki2_lssh[] = { cctki2_cctkGH->CCTK_LSSH(0,0) }; \
+ int const cctki2_istr1 CCTK_ATTRIBUTE_UNUSED = (istr); \
+ /* Loop over all faces, edges, and corners */ \
+ for (int cctki2_idir=-1; cctki2_idir<=+1; ++cctki2_idir) { \
+ int cctki2_any_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 0) || (cctki2_idir==+1 ? cctki2_bbox[1] : 0); \
+ if (cctki2_any_bbox) { \
+ int const cctki2_bmin[] = { \
+ cctki2_idir==-1 ? 0 : cctki2_idir==0 ? cctki2_blo[0] : cctki2_lssh[0] - cctki2_bhi[0], \
+ }; \
+ int const cctki2_bmax[] = { \
+ cctki2_idir==-1 ? cctki2_blo[0] : cctki2_idir==0 ? cctki2_lssh[0] - cctki2_bhi[0] : cctki2_lssh[0], \
+ }; \
+ CCTK_LOOP1STR_NORMAL(name##_boundaries, \
+ i, \
+ ni, \
+ cctki2_idir, \
+ cctki2_bmin[0], \
+ cctki2_bmax[0], \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_istr1) { \
+
+#define CCTK_ENDLOOP1STR_BOUNDARIES(name) \
+ } CCTK_ENDLOOP1STR_NORMAL(name##_boundaries); \
+ } /* if bbox */ \
+ } /* for dir */ \
+ typedef cctki2_loop1_boundaries_##name cctki2_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INTBOUNDARIES */
+
+#define CCTK_LOOP1_INTBOUNDARIES(name, cctkGH, \
+ i, \
+ ni, \
+ iblo, \
+ ibhi, \
+ ibboxlo, \
+ ibboxhi) \
+ CCTK_LOOP1STR_INTBOUNDARIES(name, (cctkGH), \
+ i, \
+ ni, \
+ (iblo), \
+ (ibhi), \
+ (ibboxlo), \
+ (ibboxhi), \
+ 1) \
+
+#define CCTK_ENDLOOP1_INTBOUNDARIES(name) \
+ CCTK_ENDLOOP1STR_INTBOUNDARIES(name) \
+
+#define CCTK_LOOP1STR_INTBOUNDARIES(name, cctkGH, \
+ i, \
+ ni, \
+ iblo, \
+ ibhi, \
+ ibboxlo, \
+ ibboxhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop1_intboundaries_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 1) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP1_INTBOUNDARIES can only be used in 1 dimensions"); \
+ } \
+ int const cctki2_blo[] = { (iblo) }; \
+ int const cctki2_bhi[] = { (ibhi) }; \
+ int const cctki2_bbox[] = { (ibboxlo), (ibboxhi) }; \
+ int const cctki2_lssh[] = { cctki2_cctkGH->CCTK_LSSH(0,0) }; \
+ int const cctki2_istr1 CCTK_ATTRIBUTE_UNUSED = (istr); \
+ /* Loop over all faces, edges, and corners */ \
+ for (int cctki2_idir=-1; cctki2_idir<=+1; ++cctki2_idir) { \
+ int cctki2_any_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 0) || (cctki2_idir==+1 ? cctki2_bbox[1] : 0); \
+ int cctki2_all_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 1) && (cctki2_idir==+1 ? cctki2_bbox[1] : 1); \
+ if (cctki2_all_bbox && cctki2_any_bbox) { \
+ int const cctki2_bmin[] = { \
+ cctki2_idir==-1 ? 0 : cctki2_idir==0 ? cctki2_blo[0] : cctki2_lssh[0] - cctki2_bhi[0], \
+ }; \
+ int const cctki2_bmax[] = { \
+ cctki2_idir==-1 ? cctki2_blo[0] : cctki2_idir==0 ? cctki2_lssh[0] - cctki2_bhi[0] : cctki2_lssh[0], \
+ }; \
+ CCTK_LOOP1STR_NORMAL(name##_intboundaries, \
+ i, \
+ ni, \
+ cctki2_idir, \
+ cctki2_bmin[0], \
+ cctki2_bmax[0], \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_istr1) { \
+
+#define CCTK_ENDLOOP1STR_INTBOUNDARIES(name) \
+ } CCTK_ENDLOOP1STR_NORMAL(name##_intboundaries); \
+ } /* if bbox */ \
+ } /* for dir */ \
+ typedef cctki2_loop1_intboundaries_##name cctki2_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_ALL */
+
+#define CCTK_LOOP1_ALL(name, cctkGH, \
+ i) \
+ CCTK_LOOP1STR_ALL(name, (cctkGH), \
+ i, \
+ 1) \
+
+#define CCTK_ENDLOOP1_ALL(name) \
+ CCTK_ENDLOOP1STR_ALL(name) \
+
+#define CCTK_LOOP1STR_ALL(name, cctkGH, \
+ i, \
+ istr) \
+ do { \
+ typedef int cctki3_loop1_all_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 1) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP1_ALL can only be used in 1 dimensions"); \
+ } \
+ CCTK_LOOP1STR(name##_all, \
+ i, \
+ 0, \
+ cctki3_cctkGH->CCTK_LSSH(0,0), \
+ cctki3_cctkGH->cctk_lsh[0], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP1STR_ALL(name) \
+ } CCTK_ENDLOOP1STR(name##_all); \
+ typedef cctki3_loop1_all_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INT */
+
+#define CCTK_LOOP1_INT(name, cctkGH, \
+ i) \
+ CCTK_LOOP1STR_INT(name, (cctkGH), \
+ i, \
+ 1) \
+
+#define CCTK_ENDLOOP1_INT(name) \
+ CCTK_ENDLOOP1STR_INT(name) \
+
+#define CCTK_LOOP1STR_INT(name, cctkGH, \
+ i, \
+ istr) \
+ do { \
+ typedef int cctki3_loop1_int_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 1) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP1_INT can only be used in 1 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [2]; \
+ CCTK_INT cctki3_is_ghostbnd[2]; \
+ CCTK_INT cctki3_is_symbnd [2]; \
+ CCTK_INT cctki3_is_physbnd [2]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 2, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP1STR_INTERIOR(name##_int, \
+ cctki3_cctkGH, \
+ i, \
+ cctki3_bndsize[0], \
+ cctki3_bndsize[1], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP1STR_INT(name) \
+ } CCTK_ENDLOOP1STR_INTERIOR(name##_int); \
+ typedef cctki3_loop1_int_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_BND */
+
+#define CCTK_LOOP1_BND(name, cctkGH, \
+ i, \
+ ni) \
+ CCTK_LOOP1STR_BND(name, (cctkGH), \
+ i, \
+ ni, \
+ 1) \
+
+#define CCTK_ENDLOOP1_BND(name) \
+ CCTK_ENDLOOP1STR_BND(name) \
+
+#define CCTK_LOOP1STR_BND(name, cctkGH, \
+ i, \
+ ni, \
+ istr) \
+ do { \
+ typedef int cctki3_loop1_bnd_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 1) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP1_BND can only be used in 1 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [2]; \
+ CCTK_INT cctki3_is_ghostbnd[2]; \
+ CCTK_INT cctki3_is_symbnd [2]; \
+ CCTK_INT cctki3_is_physbnd [2]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize, cctki3_is_physbnd)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 2, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP1STR_BOUNDARIES(name##_bnd, \
+ cctki3_cctkGH, \
+ i, \
+ ni, \
+ cctki3_bndsize[0], \
+ cctki3_bndsize[1], \
+ cctki3_is_physbnd[0], \
+ cctki3_is_physbnd[1], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP1STR_BND(name) \
+ } CCTK_ENDLOOP1STR_BOUNDARIES(name##_bnd); \
+ typedef cctki3_loop1_bnd_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INTBND */
+
+#define CCTK_LOOP1_INTBND(name, cctkGH, \
+ i, \
+ ni) \
+ CCTK_LOOP1STR_INTBND(name, (cctkGH), \
+ i, \
+ ni, \
+ 1) \
+
+#define CCTK_ENDLOOP1_INTBND(name) \
+ CCTK_ENDLOOP1STR_INTBND(name) \
+
+#define CCTK_LOOP1STR_INTBND(name, cctkGH, \
+ i, \
+ ni, \
+ istr) \
+ do { \
+ typedef int cctki3_loop1_intbnd_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 1) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP1_INTBND can only be used in 1 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [2]; \
+ CCTK_INT cctki3_is_ghostbnd[2]; \
+ CCTK_INT cctki3_is_symbnd [2]; \
+ CCTK_INT cctki3_is_physbnd [2]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize, cctki3_is_physbnd)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 2, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP1STR_INTBOUNDARIES(name##_intbnd, \
+ cctki3_cctkGH, \
+ i, \
+ ni, \
+ cctki3_bndsize[0], \
+ cctki3_bndsize[1], \
+ cctki3_is_physbnd[0], \
+ cctki3_is_physbnd[1], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP1STR_INTBND(name) \
+ } CCTK_ENDLOOP1STR_INTBOUNDARIES(name##_intbnd); \
+ typedef cctki3_loop1_intbnd_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+#endif /* #ifdef CCODE */
+
+
+
+#ifdef FCODE
+
+/* LOOP */
+
+#define CCTK_LOOP1_DECLARE(name) \
+ && integer :: name/**/_imin \
+ && integer :: name/**/_imax \
+ && integer :: name/**/_istr \
+
+#define CCTK_LOOP1_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP1(name, \
+ i, \
+ imin, \
+ imax, \
+ ilsh) \
+ CCTK_LOOP1STR(name, \
+ i, \
+ imin, \
+ imax, \
+ ilsh, \
+ 1) \
+
+#define CCTK_LOOP1STR(name, \
+ i, \
+ imin, \
+ imax, \
+ ilsh, \
+ istr) \
+ && name/**/_imin = imin \
+ && name/**/_imax = imax \
+ && name/**/_istr = istr \
+ && do i = name/**/_imin, name/**/_imax \
+
+#define CCTK_ENDLOOP1(name) \
+ CCTK_ENDLOOP1STR(name) \
+
+#define CCTK_ENDLOOP1STR(name) \
+ && end do \
+
+
+
+/* LOOP_ALL */
+
+#define CCTK_LOOP1_ALL_DECLARE(name) \
+ CCTK_LOOP1_DECLARE(name) \
+
+#define CCTK_LOOP1_ALL_OMP_PRIVATE(name) \
+ CCTK_LOOP1_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP1_ALL(name, \
+ i) \
+ CCTK_LOOP1STR_ALL(name, \
+ i, \
+ 1) \
+
+#define CCTK_LOOP1STR_ALL(name, \
+ i, \
+ istr) \
+ CCTK_LOOP1STR(name, \
+ i, \
+ 1, \
+ CCTK_LSSH(0,1), \
+ cctk_lsh(1), \
+ istr) \
+
+#define CCTK_ENDLOOP1_ALL(name) \
+ CCTK_ENDLOOP1STR_ALL(name) \
+
+#define CCTK_ENDLOOP1STR_ALL(name) \
+ CCTK_ENDLOOP1(name) \
+
+
+
+/* LOOP_INTERIOR */
+
+#define CCTK_LOOP1_INTERIOR_DECLARE(name) \
+ CCTK_LOOP1_DECLARE(name) \
+
+#define CCTK_LOOP1_INTERIOR_OMP_PRIVATE(name) \
+ CCTK_LOOP1_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP1_INTERIOR(name, \
+ i, \
+ iblo, \
+ ibhi) \
+ CCTK_LOOP1STR_INTERIOR(name, \
+ i, \
+ iblo, \
+ ibhi, \
+ 1) \
+
+#define CCTK_LOOP1STR_INTERIOR(name, \
+ i, \
+ iblo, \
+ ibhi, \
+ istr) \
+ CCTK_LOOP1STR(name, \
+ i, \
+ (iblo), \
+ CCTK_LSSH(0,1)-(ibhi), \
+ cctk_lsh(1), \
+ istr) \
+
+#define CCTK_ENDLOOP1_INTERIOR(name) \
+ CCTK_ENDLOOP1STR_INTERIOR(name) \
+
+#define CCTK_ENDLOOP1STR_INTERIOR(name) \
+ CCTK_ENDLOOP1(name) \
+
+
+
+/* LOOP_BOUNDARIES */
+
+#define CCTK_LOOP1_BOUNDARIES_DECLARE(name) \
+ CCTK_LOOP1_DECLARE(name) \
+ && integer :: lc_bmin(1), lc_bmax(1) \
+ && integer :: lc_blo(1), lc_bhi(1) \
+ && integer :: lc_istr \
+ && integer :: lc_dir, lc_face \
+ && integer :: lc_d \
+
+#define CCTK_LOOP1_BOUNDARIES_OMP_PRIVATE(name) \
+ CCTK_LOOP1_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP1_BOUNDARIES(name, \
+ i, \
+ iblo, \
+ ibhi) \
+ CCTK_LOOP1STR_BOUNDARIES(name, \
+ i, \
+ iblo, \
+ ibhi, \
+ 1) \
+
+#define CCTK_LOOP1STR_BOUNDARIES(name, \
+ i, \
+ iblo, \
+ ibhi, \
+ istr) \
+ && lc_blo = (/ iblo /) \
+ && lc_bhi = (/ ibhi /) \
+ && lc_istr = istr \
+ && do lc_dir=1,1 \
+ && do lc_face=1,2 \
+ && do lc_d=1,1 \
+ && lc_bmin(lc_d) = 1 \
+ && lc_bmax(lc_d) = CCTK_LSSH(0,lc_d) \
+ && if (lc_d<lc_dir) then \
+ && lc_bmin(lc_d) = lc_bmin(lc_d)+lc_blo(lc_d) \
+ && lc_bmax(lc_d) = lc_bmax(lc_d)-lc_bhi(lc_d) \
+ && end if \
+ && end do \
+ && if (lc_face==1) then \
+ && lc_bmax(lc_dir) = lc_bmin(lc_dir)+lc_blo(lc_dir) \
+ && else \
+ && lc_bmin(lc_dir) = lc_bmax(lc_dir)-lc_bhi(lc_dir) \
+ && end if \
+ CCTK_LOOP1STR(name, \
+ i, \
+ lc_bmin(1), \
+ lc_bmax(1), \
+ cctk_lsh(1), \
+ lc_istr) \
+
+#define CCTK_ENDLOOP1_BOUNDARIES(name) \
+ CCTK_ENDLOOP1STR_BOUNDARIES(name) \
+
+#define CCTK_ENDLOOP1STR_BOUNDARIES(name) \
+ CCTK_ENDLOOP1(name) \
+ && end do /* face */ \
+ && end do /* dir */ \
-#define CCTK_LOOP1(name, i, \
- imin, imax, ilsh) \
- do { \
- typedef int lc_loop1_##name; \
- int const lc_imin = (imin); \
- int const lc_imax = (imax); \
- for (int i=lc_imin; i<lc_imax; ++i) {
-#define CCTK_ENDLOOP1(name) \
- } \
- typedef lc_loop1_##name lc_ensure_proper_nesting; \
- } while (0)
-
-#define CCTK_LOOP1_ALL(name, cctkGH, i) \
- do { \
- typedef int lc_loop1_all_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 1) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP1_ALL can only be used in 1 dimension"); \
- } \
- CCTK_LOOP1(name##_all, \
- i, \
- 0, \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,0)], \
- lc_cctkGH->cctk_lsh[0]) {
-#define CCTK_ENDLOOP1_ALL(name) \
- } CCTK_ENDLOOP1(name##_all); \
- typedef lc_loop1_all_##name lc_ensure_proper_nesting; \
- } while (0)
-
-#define CCTK_LOOP1_INTERIOR(name, cctkGH, i, \
- iblo, ibhi) \
- do { \
- typedef int lc_loop1_interior_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 1) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP1_INTERIOR can only be used in 1 dimension"); \
- } \
- CCTK_LOOP1(name##_interior, \
- i, \
- (iblo), \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,0)]-(ibhi), \
- lc_cctkGH->cctk_lsh[0]) {
-#define CCTK_ENDLOOP1_INTERIOR(name) \
- } CCTK_ENDLOOP1(name##_interior); \
- typedef lc_loop1_interior_##name lc_ensure_proper_nesting; \
- } while(0)
-
-#define CCTK_LOOP1_BOUNDARIES(name, cctkGH, i, \
- iblo, ibhi) \
- do { \
- typedef int lc_loop1_boundaries_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 1) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP1_BOUNDARIES can only be used in 1 dimension"); \
- } \
- int const lc_blo[] = { (iblo) }; \
- int const lc_bhi[] = { (ibhi) }; \
- for (int lc_dir=0; lc_dir<1; ++lc_dir) { \
- for (int lc_face=0; lc_face<2; ++lc_face) { \
- int lc_bmin[1], lc_bmax[1]; \
- for (int lc_d=0; lc_d<1; ++lc_d) { \
- lc_bmin[lc_d] = 0; \
- lc_bmax[lc_d] = lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,lc_d)]; \
- if (lc_d<lc_dir) { \
- lc_bmin[lc_d] += lc_blo[lc_d]; \
- lc_bmax[lc_d] -= lc_bhi[lc_d]; \
- } \
- } \
- if (lc_face==0) { \
- lc_bmax[lc_dir] = lc_bmin[lc_dir]+lc_blo[lc_dir]; \
- } else { \
- lc_bmin[lc_dir] = lc_bmax[lc_dir]-lc_bhi[lc_dir]; \
- } \
- CCTK_LOOP1(name##_boundaries, \
- i, \
- lc_bmin[0], \
- lc_bmax[0], \
- lc_cctkGH->cctk_lsh[0]) {
-#define CCTK_ENDLOOP1_BOUNDARIES(name) \
- } CCTK_ENDLOOP1(name##_boundaries); \
- } /* for face */ \
- } /* for dir */ \
- typedef lc_loop1_boundaries_##name lc_ensure_proper_nesting; \
- } while (0)
+#endif /* #ifdef FCODE */
/* 2D */
-#define CCTK_LOOP2(name, i,j, \
- imin,jmin, imax,jmax, ilsh,jlsh) \
- do { \
- typedef int lc_loop2_##name; \
- int const lc_imin = (imin); \
- int const lc_jmin = (jmin); \
- int const lc_imax = (imax); \
- int const lc_jmax = (jmax); \
- for (int j=lc_jmin; j<lc_jmax; ++j) { \
- for (int i=lc_imin; i<lc_imax; ++i) {
-#define CCTK_ENDLOOP2(name) \
- } \
- } \
- typedef lc_loop2_##name lc_ensure_proper_nesting; \
- } while (0)
-
-#define CCTK_LOOP2_ALL(name, cctkGH, i,j) \
- do { \
- typedef int lc_loop2_all_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 2) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP2_ALL can only be used in 2 dimensions"); \
- } \
- CCTK_LOOP2(name##_all, \
- i,j, \
- 0,0, \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,0)], \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,1)], \
- lc_cctkGH->cctk_lsh[0], \
- lc_cctkGH->cctk_lsh[1]) {
-#define CCTK_ENDLOOP2_ALL(name) \
- } CCTK_ENDLOOP2(name##_all); \
- typedef lc_loop2_all_##name lc_ensure_proper_nesting; \
- } while (0)
-
-#define CCTK_LOOP2_INTERIOR(name, cctkGH, i,j, \
- iblo,jblo, ibhi,jbhi) \
- do { \
- typedef int lc_loop2_interior_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 2) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP2_INTERIOR can only be used in 2 dimensions"); \
- } \
- CCTK_LOOP2(name##_interior, \
- i,j, \
- (iblo),(jblo), \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,0)]-(ibhi), \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,1)]-(jbhi), \
- lc_cctkGH->cctk_lsh[0], \
- lc_cctkGH->cctk_lsh[1]) {
-#define CCTK_ENDLOOP2_INTERIOR(name) \
- } CCTK_ENDLOOP2(name##_interior); \
- typedef lc_loop2_interior_##name lc_ensure_proper_nesting; \
- } while(0)
-
-#define CCTK_LOOP2_BOUNDARIES(name, cctkGH, i,j, \
- iblo,jblo, ibhi,jbhi) \
- do { \
- typedef int lc_loop2_boundaries_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 2) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP2_BOUNDARIES can only be used in 2 dimensions"); \
- } \
- int const lc_blo[] = { (iblo),(jblo) }; \
- int const lc_bhi[] = { (ibhi),(jbhi) }; \
- for (int lc_dir=0; lc_dir<2; ++lc_dir) { \
- for (int lc_face=0; lc_face<2; ++lc_face) { \
- int lc_bmin[2], lc_bmax[2]; \
- for (int lc_d=0; lc_d<2; ++lc_d) { \
- lc_bmin[lc_d] = 0; \
- lc_bmax[lc_d] = lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,lc_d)]; \
- if (lc_d<lc_dir) { \
- lc_bmin[lc_d] += lc_blo[lc_d]; \
- lc_bmax[lc_d] -= lc_bhi[lc_d]; \
- } \
- } \
- if (lc_face==0) { \
- lc_bmax[lc_dir] = lc_bmin[lc_dir]+lc_blo[lc_dir]; \
- } else { \
- lc_bmin[lc_dir] = lc_bmax[lc_dir]-lc_bhi[lc_dir]; \
- } \
- CCTK_LOOP2(name##_boundaries, \
- i,j, \
- lc_bmin[0],lc_bmin[1], \
- lc_bmax[0],lc_bmax[1], \
- lc_cctkGH->cctk_lsh[0], \
- lc_cctkGH->cctk_lsh[1]) {
-#define CCTK_ENDLOOP2_BOUNDARIES(name) \
- } CCTK_ENDLOOP2(name##_boundaries); \
- } /* for face */ \
- } /* for dir */ \
- typedef lc_loop2_boundaries_##name lc_ensure_proper_nesting; \
- } while (0)
+#ifdef CCODE
+/* LOOP */
+#define CCTK_LOOP2_NORMAL(name, \
+ i,j, \
+ ni,nj, \
+ idir,jdir, \
+ imin,jmin, \
+ imax,jmax, \
+ ilsh,jlsh) \
+ CCTK_LOOP2STR_NORMAL(name, \
+ i,j, \
+ ni,nj, \
+ (idir),(jdir), \
+ (imin),(jmin), \
+ (imax),(jmax), \
+ (ilsh),(jlsh), \
+ 1) \
-/* 3D */
+#define CCTK_ENDLOOP2_NORMAL(name) \
+ CCTK_ENDLOOP2STR_NORMAL(name) \
-#define CCTK_LOOP3(name, i,j,k, \
- imin,jmin,kmin, imax,jmax,kmax, ilsh,jlsh,klsh) \
- do { \
- typedef int lc_loop3_##name; \
- int const lc_imin = (imin); \
- int const lc_jmin = (jmin); \
- int const lc_kmin = (kmin); \
- int const lc_imax = (imax); \
- int const lc_jmax = (jmax); \
- int const lc_kmax = (kmax); \
- for (int k=lc_kmin; k<lc_kmax; ++k) { \
- for (int j=lc_jmin; j<lc_jmax; ++j) { \
- for (int i=lc_imin; i<lc_imax; ++i) {
-#define CCTK_ENDLOOP3(name) \
- } \
- } \
- } \
- typedef lc_loop3_##name lc_ensure_proper_nesting; \
- } while (0)
-
-#define CCTK_LOOP3_ALL(name, cctkGH, i,j,k) \
- do { \
- typedef int lc_loop3_all_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 3) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP3_ALL can only be used in 3 dimensions"); \
- } \
- CCTK_LOOP3(name##_all, \
- i,j,k, \
- 0,0,0, \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,0)], \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,1)], \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,2)], \
- lc_cctkGH->cctk_lsh[0], \
- lc_cctkGH->cctk_lsh[1], \
- lc_cctkGH->cctk_lsh[2]) {
-#define CCTK_ENDLOOP3_ALL(name) \
- } CCTK_ENDLOOP3(name##_all); \
- typedef lc_loop3_all_##name lc_ensure_proper_nesting; \
- } while (0)
-
-#define CCTK_LOOP3_INTERIOR(name, cctkGH, i,j,k, \
- iblo,jblo,kblo, ibhi,jbhi,kbhi) \
- do { \
- typedef int lc_loop3_interior_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 3) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP3_INTERIOR can only be used in 3 dimensions"); \
- } \
- CCTK_LOOP3(name##_interior, \
- i,j,k, \
- (iblo),(jblo),(kblo), \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,0)]-(ibhi), \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,1)]-(jbhi), \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,2)]-(kbhi), \
- lc_cctkGH->cctk_lsh[0], \
- lc_cctkGH->cctk_lsh[1], \
- lc_cctkGH->cctk_lsh[2]) {
-#define CCTK_ENDLOOP3_INTERIOR(name) \
- } CCTK_ENDLOOP3(name##_interior); \
- typedef lc_loop3_interior_##name lc_ensure_proper_nesting; \
- } while(0)
-
-#define CCTK_LOOP3_BOUNDARIES(name, cctkGH, i,j,k, \
- iblo,jblo,kblo, ibhi,jbhi,kbhi) \
- do { \
- typedef int lc_loop3_boundaries_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 3) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP3_BOUNDARIES can only be used in 3 dimensions"); \
- } \
- int const lc_blo[] = { (iblo),(jblo),(kblo) }; \
- int const lc_bhi[] = { (ibhi),(jbhi),(kbhi) }; \
- for (int lc_dir=0; lc_dir<3; ++lc_dir) { \
- for (int lc_face=0; lc_face<2; ++lc_face) { \
- int lc_bmin[3], lc_bmax[3]; \
- for (int lc_d=0; lc_d<3; ++lc_d) { \
- lc_bmin[lc_d] = 0; \
- lc_bmax[lc_d] = lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,lc_d)]; \
- if (lc_d<lc_dir) { \
- lc_bmin[lc_d] += lc_blo[lc_d]; \
- lc_bmax[lc_d] -= lc_bhi[lc_d]; \
- } \
- } \
- if (lc_face==0) { \
- lc_bmax[lc_dir] = lc_bmin[lc_dir]+lc_blo[lc_dir]; \
- } else { \
- lc_bmin[lc_dir] = lc_bmax[lc_dir]-lc_bhi[lc_dir]; \
- } \
- CCTK_LOOP3(name##_boundaries, \
- i,j,k, \
- lc_bmin[0],lc_bmin[1],lc_bmin[2], \
- lc_bmax[0],lc_bmax[1],lc_bmax[2], \
- lc_cctkGH->cctk_lsh[0], \
- lc_cctkGH->cctk_lsh[1], \
- lc_cctkGH->cctk_lsh[2]) {
-#define CCTK_ENDLOOP3_BOUNDARIES(name) \
- } CCTK_ENDLOOP3(name##_boundaries); \
- } /* for face */ \
- } /* for dir */ \
- typedef lc_loop3_boundaries_##name lc_ensure_proper_nesting; \
- } while (0)
+#define CCTK_LOOP2STR_NORMAL(name, \
+ i,j, \
+ ni,nj, \
+ idir,jdir, \
+ imin,jmin, \
+ imax,jmax, \
+ ilsh,jlsh, \
+ istr) \
+ do { \
+ typedef int cctki0_loop2_normal_##name; \
+ int const cctki0_idir = (idir); \
+ int const cctki0_jdir = (jdir); \
+ int const cctki0_imin = (imin); \
+ int const cctki0_jmin = (jmin); \
+ int const cctki0_imax = (imax); \
+ int const cctki0_jmax = (jmax); \
+ int const cctki0_istr CCTK_ATTRIBUTE_UNUSED = (istr); \
+ assert(cctki0_istr == 1); \
+ _Pragma("omp for") \
+ for (int j=cctki0_jmin; j<cctki0_jmax; ++j) { \
+ for (int i=cctki0_imin; i<cctki0_imax; ++i) { \
+ int const ni CCTK_ATTRIBUTE_UNUSED = cctki0_idir<0 ? i+1 : cctki0_idir==0 ? 0 : cctki0_imax-i; \
+ int const nj CCTK_ATTRIBUTE_UNUSED = cctki0_jdir<0 ? j+1 : cctki0_jdir==0 ? 0 : cctki0_jmax-j; \
+ { \
+#define CCTK_ENDLOOP2STR_NORMAL(name) \
+ } \
+ } \
+ } \
+ typedef cctki0_loop2_normal_##name cctki0_ensure_proper_nesting; \
+ } while (0) \
-/* 4D */
-#define CCTK_LOOP4(name, i,j,k,l, \
- imin,jmin,kmin,lmin, imax,jmax,kmax,lmax, ilsh,jlsh,klsh,llsh) \
- do { \
- typedef int lc_loop4_##name; \
- int const lc_imin = (imin); \
- int const lc_jmin = (jmin); \
- int const lc_kmin = (kmin); \
- int const lc_lmin = (lmin); \
- int const lc_imax = (imax); \
- int const lc_jmax = (jmax); \
- int const lc_kmax = (kmax); \
- int const lc_lmax = (lmax); \
- for (int l=lc_lmin; l<lc_lmax; ++l) { \
- for (int k=lc_kmin; k<lc_kmax; ++k) { \
- for (int j=lc_jmin; j<lc_jmax; ++j) { \
- for (int i=lc_imin; i<lc_imax; ++i) {
-#define CCTK_ENDLOOP4(name) \
- } \
- } \
- } \
- } \
- typedef lc_loop4_##name lc_ensure_proper_nesting; \
- } while (0)
-
-#define CCTK_LOOP4_ALL(name, cctkGH, i,j,k,l) \
- do { \
- typedef int lc_loop4_all_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 4) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP4_ALL can only be used in 4 dimensions"); \
- } \
- CCTK_LOOP4(name##_all, \
- i,j,k,l, \
- 0,0,0,0, \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,0)], \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,1)], \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,2)], \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,3)], \
- lc_cctkGH->cctk_lsh[0], \
- lc_cctkGH->cctk_lsh[1], \
- lc_cctkGH->cctk_lsh[2], \
- lc_cctkGH->cctk_lsh[3]) {
-#define CCTK_ENDLOOP4_ALL(name) \
- } CCTK_ENDLOOP4(name##_all); \
- typedef lc_loop4_all_##name lc_ensure_proper_nesting; \
- } while (0)
-
-#define CCTK_LOOP4_INTERIOR(name, cctkGH, i,j,k,l, \
- iblo,jblo,kblo,lblo, ibhi,jbhi,kbhi,lbhi) \
- do { \
- typedef int lc_loop4_interior_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 4) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP4_INTERIOR can only be used in 4 dimensions"); \
- } \
- CCTK_LOOP4(name##_interior, \
- i,j,k,l, \
- (iblo),(jblo),(kblo),(lblo), \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,0)]-(ibhi), \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,1)]-(jbhi), \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,2)]-(kbhi), \
- lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,3)]-(lbhi), \
- lc_cctkGH->cctk_lsh[0], \
- lc_cctkGH->cctk_lsh[1], \
- lc_cctkGH->cctk_lsh[2], \
- lc_cctkGH->cctk_lsh[3]) {
-#define CCTK_ENDLOOP4_INTERIOR(name) \
- } CCTK_ENDLOOP4(name##_interior); \
- typedef lc_loop4_interior_##name lc_ensure_proper_nesting; \
- } while(0)
-
-#define CCTK_LOOP4_BOUNDARIES(name, cctkGH, i,j,k,l, \
- iblo,jblo,kblo,lblo, ibhi,jbhi,kbhi,lbhi) \
- do { \
- typedef int lc_loop4_boundaries_##name; \
- cGH const *CCTK_RESTRICT const lc_cctkGH = (cctkGH); \
- if (lc_cctkGH->cctk_dim != 4) { \
- CCTK_WARN (CCTK_WARN_ABORT, \
- "Macro CCTK_LOOP4_BOUNDARIES can only be used in 4 dimensions"); \
- } \
- int const lc_blo[] = { (iblo),(jblo),(kblo),(lblo) }; \
- int const lc_bhi[] = { (ibhi),(jbhi),(kbhi),(lbhi) }; \
- for (int lc_dir=0; lc_dir<4; ++lc_dir) { \
- for (int lc_face=0; lc_face<2; ++lc_face) { \
- int lc_bmin[4], lc_bmax[4]; \
- for (int lc_d=0; lc_d<4; ++lc_d) { \
- lc_bmin[lc_d] = 0; \
- lc_bmax[lc_d] = lc_cctkGH->cctk_lssh[CCTK_LSSH_IDX(0,lc_d)]; \
- if (lc_d<lc_dir) { \
- lc_bmin[lc_d] += lc_blo[lc_d]; \
- lc_bmax[lc_d] -= lc_bhi[lc_d]; \
- } \
- } \
- if (lc_face==0) { \
- lc_bmax[lc_dir] = lc_bmin[lc_dir]+lc_blo[lc_dir]; \
- } else { \
- lc_bmin[lc_dir] = lc_bmax[lc_dir]-lc_bhi[lc_dir]; \
- } \
- CCTK_LOOP4(name##_boundaries, \
- i,j,k,l, \
- lc_bmin[0],lc_bmin[1],lc_bmin[2],lc_bmin[3], \
- lc_bmax[0],lc_bmax[1],lc_bmax[2],lc_bmax[3], \
- lc_cctkGH->cctk_lsh[0], \
- lc_cctkGH->cctk_lsh[1], \
- lc_cctkGH->cctk_lsh[2], \
- lc_cctkGH->cctk_lsh[3]) {
-#define CCTK_ENDLOOP4_BOUNDARIES(name) \
- } CCTK_ENDLOOP4(name##_boundaries); \
- } /* for face */ \
- } /* for dir */ \
- typedef lc_loop4_boundaries_##name lc_ensure_proper_nesting; \
- } while (0)
-
-
-
-#endif
+#define CCTK_LOOP2(name, \
+ i,j, \
+ imin,jmin, \
+ imax,jmax, \
+ ilsh,jlsh) \
+ CCTK_LOOP2STR(name, \
+ i,j, \
+ (imin),(jmin), \
+ (imax),(jmax), \
+ (ilsh),(jlsh), \
+ 1) \
+
+#define CCTK_ENDLOOP2(name) \
+ CCTK_ENDLOOP2STR(name) \
+
+#define CCTK_LOOP2STR(name, \
+ i,j, \
+ imin,jmin, \
+ imax,jmax, \
+ ilsh,jlsh, \
+ istr) \
+ CCTK_LOOP2STR_NORMAL(name, \
+ i,j, \
+ cctki1_ni,cctki1_nj, \
+ 0,0, \
+ imin,jmin, \
+ imax,jmax, \
+ ilsh,jlsh, \
+ istr) \
+
+#define CCTK_ENDLOOP2STR(name) \
+ CCTK_ENDLOOP2STR_NORMAL(name) \
+
+
+
+/* LOOP_INTERIOR */
+
+#define CCTK_LOOP2_INTERIOR(name, cctkGH, \
+ i,j, \
+ iblo,jblo, \
+ ibhi,jbhi) \
+ CCTK_LOOP2STR_INTERIOR(name, (cctkGH), \
+ i,j, \
+ (iblo),(jblo), \
+ (ibhi),(jbhi), \
+ 1) \
+
+#define CCTK_ENDLOOP2_INTERIOR(name) \
+ CCTK_ENDLOOP2STR_INTERIOR(name) \
+
+#define CCTK_LOOP2STR_INTERIOR(name, cctkGH, \
+ i,j, \
+ iblo,jblo, \
+ ibhi,jbhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop2_interior_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 2) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP2_INTERIOR can only be used in 2 dimensions"); \
+ } \
+ CCTK_LOOP2STR(name##_interior, \
+ i,j, \
+ (iblo),(jblo), \
+ cctki2_cctkGH->CCTK_LSSH(0,0)-(ibhi), \
+ cctki2_cctkGH->CCTK_LSSH(0,1)-(jbhi), \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_cctkGH->cctk_lsh[1], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP2STR_INTERIOR(name) \
+ } CCTK_ENDLOOP2STR(name##_interior); \
+ typedef cctki2_loop2_interior_##name cctki2_ensure_proper_nesting; \
+ } while(0) \
+
+
+
+/* LOOP_BOUNDARIES */
+
+#define CCTK_LOOP2_BOUNDARIES(name, cctkGH, \
+ i,j, \
+ ni,nj, \
+ iblo,jblo, \
+ ibhi,jbhi, \
+ ibboxlo,jbboxlo, \
+ ibboxhi,jbboxhi) \
+ CCTK_LOOP2STR_BOUNDARIES(name, (cctkGH), \
+ i,j, \
+ ni,nj, \
+ (iblo),(jblo), \
+ (ibhi),(jbhi), \
+ (ibboxlo),(jbboxlo), \
+ (ibboxhi),(jbboxhi), \
+ 1) \
+
+#define CCTK_ENDLOOP2_BOUNDARIES(name) \
+ CCTK_ENDLOOP2STR_BOUNDARIES(name) \
+
+#define CCTK_LOOP2STR_BOUNDARIES(name, cctkGH, \
+ i,j, \
+ ni,nj, \
+ iblo,jblo, \
+ ibhi,jbhi, \
+ ibboxlo,jbboxlo, \
+ ibboxhi,jbboxhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop2_boundaries_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 2) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP2_BOUNDARIES can only be used in 2 dimensions"); \
+ } \
+ int const cctki2_blo[] = { (iblo),(jblo) }; \
+ int const cctki2_bhi[] = { (ibhi),(jbhi) }; \
+ int const cctki2_bbox[] = { (ibboxlo), (ibboxhi),(jbboxlo), (jbboxhi) }; \
+ int const cctki2_lssh[] = { cctki2_cctkGH->CCTK_LSSH(0,0),cctki2_cctkGH->CCTK_LSSH(0,1) }; \
+ int const cctki2_istr1 CCTK_ATTRIBUTE_UNUSED = (istr); \
+ /* Loop over all faces, edges, and corners */ \
+ for (int cctki2_jdir=-1; cctki2_jdir<=+1; ++cctki2_jdir) { \
+ for (int cctki2_idir=-1; cctki2_idir<=+1; ++cctki2_idir) { \
+ int cctki2_any_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 0) || (cctki2_idir==+1 ? cctki2_bbox[1] : 0)|| \
+ (cctki2_jdir==-1 ? cctki2_bbox[2] : 0) || (cctki2_jdir==+1 ? cctki2_bbox[3] : 0); \
+ if (cctki2_any_bbox) { \
+ int const cctki2_bmin[] = { \
+ cctki2_idir==-1 ? 0 : cctki2_idir==0 ? cctki2_blo[0] : cctki2_lssh[0] - cctki2_bhi[0], \
+ cctki2_jdir==-1 ? 0 : cctki2_jdir==0 ? cctki2_blo[1] : cctki2_lssh[1] - cctki2_bhi[1], \
+ }; \
+ int const cctki2_bmax[] = { \
+ cctki2_idir==-1 ? cctki2_blo[0] : cctki2_idir==0 ? cctki2_lssh[0] - cctki2_bhi[0] : cctki2_lssh[0], \
+ cctki2_jdir==-1 ? cctki2_blo[1] : cctki2_jdir==0 ? cctki2_lssh[1] - cctki2_bhi[1] : cctki2_lssh[1], \
+ }; \
+ CCTK_LOOP2STR_NORMAL(name##_boundaries, \
+ i,j, \
+ ni,nj, \
+ cctki2_idir,cctki2_jdir, \
+ cctki2_bmin[0],cctki2_bmin[1], \
+ cctki2_bmax[0],cctki2_bmax[1], \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_cctkGH->cctk_lsh[1], \
+ cctki2_istr1) { \
+
+#define CCTK_ENDLOOP2STR_BOUNDARIES(name) \
+ } CCTK_ENDLOOP2STR_NORMAL(name##_boundaries); \
+ } /* if bbox */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ typedef cctki2_loop2_boundaries_##name cctki2_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INTBOUNDARIES */
+
+#define CCTK_LOOP2_INTBOUNDARIES(name, cctkGH, \
+ i,j, \
+ ni,nj, \
+ iblo,jblo, \
+ ibhi,jbhi, \
+ ibboxlo,jbboxlo, \
+ ibboxhi,jbboxhi) \
+ CCTK_LOOP2STR_INTBOUNDARIES(name, (cctkGH), \
+ i,j, \
+ ni,nj, \
+ (iblo),(jblo), \
+ (ibhi),(jbhi), \
+ (ibboxlo),(jbboxlo), \
+ (ibboxhi),(jbboxhi), \
+ 1) \
+
+#define CCTK_ENDLOOP2_INTBOUNDARIES(name) \
+ CCTK_ENDLOOP2STR_INTBOUNDARIES(name) \
+
+#define CCTK_LOOP2STR_INTBOUNDARIES(name, cctkGH, \
+ i,j, \
+ ni,nj, \
+ iblo,jblo, \
+ ibhi,jbhi, \
+ ibboxlo,jbboxlo, \
+ ibboxhi,jbboxhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop2_intboundaries_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 2) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP2_INTBOUNDARIES can only be used in 2 dimensions"); \
+ } \
+ int const cctki2_blo[] = { (iblo),(jblo) }; \
+ int const cctki2_bhi[] = { (ibhi),(jbhi) }; \
+ int const cctki2_bbox[] = { (ibboxlo), (ibboxhi),(jbboxlo), (jbboxhi) }; \
+ int const cctki2_lssh[] = { cctki2_cctkGH->CCTK_LSSH(0,0),cctki2_cctkGH->CCTK_LSSH(0,1) }; \
+ int const cctki2_istr1 CCTK_ATTRIBUTE_UNUSED = (istr); \
+ /* Loop over all faces, edges, and corners */ \
+ for (int cctki2_jdir=-1; cctki2_jdir<=+1; ++cctki2_jdir) { \
+ for (int cctki2_idir=-1; cctki2_idir<=+1; ++cctki2_idir) { \
+ int cctki2_any_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 0) || (cctki2_idir==+1 ? cctki2_bbox[1] : 0)|| \
+ (cctki2_jdir==-1 ? cctki2_bbox[2] : 0) || (cctki2_jdir==+1 ? cctki2_bbox[3] : 0); \
+ int cctki2_all_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 1) && (cctki2_idir==+1 ? cctki2_bbox[1] : 1)&& \
+ (cctki2_jdir==-1 ? cctki2_bbox[2] : 1) && (cctki2_jdir==+1 ? cctki2_bbox[3] : 1); \
+ if (cctki2_all_bbox && cctki2_any_bbox) { \
+ int const cctki2_bmin[] = { \
+ cctki2_idir==-1 ? 0 : cctki2_idir==0 ? cctki2_blo[0] : cctki2_lssh[0] - cctki2_bhi[0], \
+ cctki2_jdir==-1 ? 0 : cctki2_jdir==0 ? cctki2_blo[1] : cctki2_lssh[1] - cctki2_bhi[1], \
+ }; \
+ int const cctki2_bmax[] = { \
+ cctki2_idir==-1 ? cctki2_blo[0] : cctki2_idir==0 ? cctki2_lssh[0] - cctki2_bhi[0] : cctki2_lssh[0], \
+ cctki2_jdir==-1 ? cctki2_blo[1] : cctki2_jdir==0 ? cctki2_lssh[1] - cctki2_bhi[1] : cctki2_lssh[1], \
+ }; \
+ CCTK_LOOP2STR_NORMAL(name##_intboundaries, \
+ i,j, \
+ ni,nj, \
+ cctki2_idir,cctki2_jdir, \
+ cctki2_bmin[0],cctki2_bmin[1], \
+ cctki2_bmax[0],cctki2_bmax[1], \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_cctkGH->cctk_lsh[1], \
+ cctki2_istr1) { \
+
+#define CCTK_ENDLOOP2STR_INTBOUNDARIES(name) \
+ } CCTK_ENDLOOP2STR_NORMAL(name##_intboundaries); \
+ } /* if bbox */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ typedef cctki2_loop2_intboundaries_##name cctki2_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_ALL */
+
+#define CCTK_LOOP2_ALL(name, cctkGH, \
+ i,j) \
+ CCTK_LOOP2STR_ALL(name, (cctkGH), \
+ i,j, \
+ 1) \
+
+#define CCTK_ENDLOOP2_ALL(name) \
+ CCTK_ENDLOOP2STR_ALL(name) \
+
+#define CCTK_LOOP2STR_ALL(name, cctkGH, \
+ i,j, \
+ istr) \
+ do { \
+ typedef int cctki3_loop2_all_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 2) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP2_ALL can only be used in 2 dimensions"); \
+ } \
+ CCTK_LOOP2STR(name##_all, \
+ i,j, \
+ 0,0, \
+ cctki3_cctkGH->CCTK_LSSH(0,0), \
+ cctki3_cctkGH->CCTK_LSSH(0,1), \
+ cctki3_cctkGH->cctk_lsh[0], \
+ cctki3_cctkGH->cctk_lsh[1], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP2STR_ALL(name) \
+ } CCTK_ENDLOOP2STR(name##_all); \
+ typedef cctki3_loop2_all_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INT */
+
+#define CCTK_LOOP2_INT(name, cctkGH, \
+ i,j) \
+ CCTK_LOOP2STR_INT(name, (cctkGH), \
+ i,j, \
+ 1) \
+
+#define CCTK_ENDLOOP2_INT(name) \
+ CCTK_ENDLOOP2STR_INT(name) \
+
+#define CCTK_LOOP2STR_INT(name, cctkGH, \
+ i,j, \
+ istr) \
+ do { \
+ typedef int cctki3_loop2_int_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 2) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP2_INT can only be used in 2 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [4]; \
+ CCTK_INT cctki3_is_ghostbnd[4]; \
+ CCTK_INT cctki3_is_symbnd [4]; \
+ CCTK_INT cctki3_is_physbnd [4]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 4, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP2STR_INTERIOR(name##_int, \
+ cctki3_cctkGH, \
+ i,j, \
+ cctki3_bndsize[0],cctki3_bndsize[2], \
+ cctki3_bndsize[1],cctki3_bndsize[3], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP2STR_INT(name) \
+ } CCTK_ENDLOOP2STR_INTERIOR(name##_int); \
+ typedef cctki3_loop2_int_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_BND */
+
+#define CCTK_LOOP2_BND(name, cctkGH, \
+ i,j, \
+ ni,nj) \
+ CCTK_LOOP2STR_BND(name, (cctkGH), \
+ i,j, \
+ ni,nj, \
+ 1) \
+
+#define CCTK_ENDLOOP2_BND(name) \
+ CCTK_ENDLOOP2STR_BND(name) \
+
+#define CCTK_LOOP2STR_BND(name, cctkGH, \
+ i,j, \
+ ni,nj, \
+ istr) \
+ do { \
+ typedef int cctki3_loop2_bnd_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 2) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP2_BND can only be used in 2 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [4]; \
+ CCTK_INT cctki3_is_ghostbnd[4]; \
+ CCTK_INT cctki3_is_symbnd [4]; \
+ CCTK_INT cctki3_is_physbnd [4]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize, cctki3_is_physbnd)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 4, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP2STR_BOUNDARIES(name##_bnd, \
+ cctki3_cctkGH, \
+ i,j, \
+ ni,nj, \
+ cctki3_bndsize[0],cctki3_bndsize[2], \
+ cctki3_bndsize[1],cctki3_bndsize[3], \
+ cctki3_is_physbnd[0],cctki3_is_physbnd[2], \
+ cctki3_is_physbnd[1],cctki3_is_physbnd[3], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP2STR_BND(name) \
+ } CCTK_ENDLOOP2STR_BOUNDARIES(name##_bnd); \
+ typedef cctki3_loop2_bnd_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INTBND */
+
+#define CCTK_LOOP2_INTBND(name, cctkGH, \
+ i,j, \
+ ni,nj) \
+ CCTK_LOOP2STR_INTBND(name, (cctkGH), \
+ i,j, \
+ ni,nj, \
+ 1) \
+
+#define CCTK_ENDLOOP2_INTBND(name) \
+ CCTK_ENDLOOP2STR_INTBND(name) \
+
+#define CCTK_LOOP2STR_INTBND(name, cctkGH, \
+ i,j, \
+ ni,nj, \
+ istr) \
+ do { \
+ typedef int cctki3_loop2_intbnd_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 2) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP2_INTBND can only be used in 2 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [4]; \
+ CCTK_INT cctki3_is_ghostbnd[4]; \
+ CCTK_INT cctki3_is_symbnd [4]; \
+ CCTK_INT cctki3_is_physbnd [4]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize, cctki3_is_physbnd)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 4, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP2STR_INTBOUNDARIES(name##_intbnd, \
+ cctki3_cctkGH, \
+ i,j, \
+ ni,nj, \
+ cctki3_bndsize[0],cctki3_bndsize[2], \
+ cctki3_bndsize[1],cctki3_bndsize[3], \
+ cctki3_is_physbnd[0],cctki3_is_physbnd[2], \
+ cctki3_is_physbnd[1],cctki3_is_physbnd[3], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP2STR_INTBND(name) \
+ } CCTK_ENDLOOP2STR_INTBOUNDARIES(name##_intbnd); \
+ typedef cctki3_loop2_intbnd_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+#endif /* #ifdef CCODE */
#ifdef FCODE
+/* LOOP */
+
+#define CCTK_LOOP2_DECLARE(name) \
+ && integer :: name/**/_imin,name/**/_jmin \
+ && integer :: name/**/_imax,name/**/_jmax \
+ && integer :: name/**/_istr \
+
+#define CCTK_LOOP2_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP2(name, \
+ i,j, \
+ imin,jmin, \
+ imax,jmax, \
+ ilsh,jlsh) \
+ CCTK_LOOP2STR(name, \
+ i,j, \
+ imin,jmin, \
+ imax,jmax, \
+ ilsh,jlsh, \
+ 1) \
+
+#define CCTK_LOOP2STR(name, \
+ i,j, \
+ imin,jmin, \
+ imax,jmax, \
+ ilsh,jlsh, \
+ istr) \
+ && name/**/_imin = imin \
+ && name/**/_jmin = jmin \
+ && name/**/_imax = imax \
+ && name/**/_jmax = jmax \
+ && name/**/_istr = istr \
+ && do j = name/**/_jmin, name/**/_jmax \
+ && do i = name/**/_imin, name/**/_imax \
+
+#define CCTK_ENDLOOP2(name) \
+ CCTK_ENDLOOP2STR(name) \
+
+#define CCTK_ENDLOOP2STR(name) \
+ && end do \
+ && end do \
+
+
+
+/* LOOP_ALL */
+
+#define CCTK_LOOP2_ALL_DECLARE(name) \
+ CCTK_LOOP2_DECLARE(name) \
+
+#define CCTK_LOOP2_ALL_OMP_PRIVATE(name) \
+ CCTK_LOOP2_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP2_ALL(name, \
+ i,j) \
+ CCTK_LOOP2STR_ALL(name, \
+ i,j, \
+ 1) \
+
+#define CCTK_LOOP2STR_ALL(name, \
+ i,j, \
+ istr) \
+ CCTK_LOOP2STR(name, \
+ i,j, \
+ 1,1, \
+ CCTK_LSSH(0,1),CCTK_LSSH(0,2), \
+ cctk_lsh(1),cctk_lsh(2), \
+ istr) \
+
+#define CCTK_ENDLOOP2_ALL(name) \
+ CCTK_ENDLOOP2STR_ALL(name) \
+
+#define CCTK_ENDLOOP2STR_ALL(name) \
+ CCTK_ENDLOOP2(name) \
+
+
+
+/* LOOP_INTERIOR */
+
+#define CCTK_LOOP2_INTERIOR_DECLARE(name) \
+ CCTK_LOOP2_DECLARE(name) \
+
+#define CCTK_LOOP2_INTERIOR_OMP_PRIVATE(name) \
+ CCTK_LOOP2_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP2_INTERIOR(name, \
+ i,j, \
+ iblo,jblo, \
+ ibhi,jbhi) \
+ CCTK_LOOP2STR_INTERIOR(name, \
+ i,j, \
+ iblo,jblo, \
+ ibhi,jbhi, \
+ 1) \
+
+#define CCTK_LOOP2STR_INTERIOR(name, \
+ i,j, \
+ iblo,jblo, \
+ ibhi,jbhi, \
+ istr) \
+ CCTK_LOOP2STR(name, \
+ i,j, \
+ (iblo),(jblo), \
+ CCTK_LSSH(0,1)-(ibhi), \
+ CCTK_LSSH(0,2)-(jbhi), \
+ cctk_lsh(1),cctk_lsh(2), \
+ istr) \
+
+#define CCTK_ENDLOOP2_INTERIOR(name) \
+ CCTK_ENDLOOP2STR_INTERIOR(name) \
+
+#define CCTK_ENDLOOP2STR_INTERIOR(name) \
+ CCTK_ENDLOOP2(name) \
+
+
+
+/* LOOP_BOUNDARIES */
+
+#define CCTK_LOOP2_BOUNDARIES_DECLARE(name) \
+ CCTK_LOOP2_DECLARE(name) \
+ && integer :: lc_bmin(2), lc_bmax(2) \
+ && integer :: lc_blo(2), lc_bhi(2) \
+ && integer :: lc_istr \
+ && integer :: lc_dir, lc_face \
+ && integer :: lc_d \
+
+#define CCTK_LOOP2_BOUNDARIES_OMP_PRIVATE(name) \
+ CCTK_LOOP2_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP2_BOUNDARIES(name, \
+ i,j, \
+ iblo,jblo, \
+ ibhi,jbhi) \
+ CCTK_LOOP2STR_BOUNDARIES(name, \
+ i,j, \
+ iblo,jblo, \
+ ibhi,jbhi, \
+ 1) \
+
+#define CCTK_LOOP2STR_BOUNDARIES(name, \
+ i,j, \
+ iblo,jblo, \
+ ibhi,jbhi, \
+ istr) \
+ && lc_blo = (/ iblo,jblo /) \
+ && lc_bhi = (/ ibhi,jbhi /) \
+ && lc_istr = istr \
+ && do lc_dir=1,2 \
+ && do lc_face=1,2 \
+ && do lc_d=1,2 \
+ && lc_bmin(lc_d) = 1 \
+ && lc_bmax(lc_d) = CCTK_LSSH(0,lc_d) \
+ && if (lc_d<lc_dir) then \
+ && lc_bmin(lc_d) = lc_bmin(lc_d)+lc_blo(lc_d) \
+ && lc_bmax(lc_d) = lc_bmax(lc_d)-lc_bhi(lc_d) \
+ && end if \
+ && end do \
+ && if (lc_face==1) then \
+ && lc_bmax(lc_dir) = lc_bmin(lc_dir)+lc_blo(lc_dir) \
+ && else \
+ && lc_bmin(lc_dir) = lc_bmax(lc_dir)-lc_bhi(lc_dir) \
+ && end if \
+ CCTK_LOOP2STR(name, \
+ i,j, \
+ lc_bmin(1),lc_bmin(2), \
+ lc_bmax(1),lc_bmax(2), \
+ cctk_lsh(1),cctk_lsh(2), \
+ lc_istr) \
+
+#define CCTK_ENDLOOP2_BOUNDARIES(name) \
+ CCTK_ENDLOOP2STR_BOUNDARIES(name) \
+
+#define CCTK_ENDLOOP2STR_BOUNDARIES(name) \
+ CCTK_ENDLOOP2(name) \
+ && end do /* face */ \
+ && end do /* dir */ \
+
+#endif /* #ifdef FCODE */
+
/* 3D */
-#define CCTK_LOOP3_DECLARE(name) \
- integer :: name/**/_imin, name/**/_jmin, name/**/_kmin && \
- integer :: name/**/_imax, name/**/_jmax, name/**/_kmax
-
-#define CCTK_LOOP3_OMP_PRIVATE(name)
-
-#define CCTK_LOOP3(name, i,j,k, \
- imin,jmin,kmin, imax,jmax,kmax, ilsh,jlsh,klsh) \
- name/**/_imin = imin && \
- name/**/_jmin = jmin && \
- name/**/_kmin = kmin && \
- name/**/_imax = imax && \
- name/**/_jmax = jmax && \
- name/**/_kmax = kmax && \
- do k = name/**/_kmin, name/**/_kmax && \
- do j = name/**/_jmin, name/**/_jmax && \
- do i = name/**/_imin, name/**/_imax
-#define CCTK_ENDLOOP3(name) \
- end do && \
- end do && \
- end do
-
-#define CCTK_LOOP3_ALL_DECLARE(name) \
- CCTK_LOOP3_DECLARE(name)
-#define CCTK_LOOP3_ALL_OMP_PRIVATE(name) \
- CCTK_LOOP3_OMP_PRIVATE(name)
-#define CCTK_LOOP3_ALL(name, i,j,k) \
- CCTK_LOOP3(name, \
- i,j,k, \
- 1,1,1, \
- CCTK_LSSH(0,1), \
- CCTK_LSSH(0,2), \
- CCTK_LSSH(0,3), \
- cctk_lsh(1),cctk_lsh(2),cctk_lsh(3))
-#define CCTK_ENDLOOP3_ALL(name) \
- CCTK_ENDLOOP3(name)
-
-#define CCTK_LOOP3_INTERIOR_DECLARE(name) \
- CCTK_LOOP3_DECLARE(name)
-#define CCTK_LOOP3_INTERIOR_OMP_PRIVATE(name) \
- CCTK_LOOP3_OMP_PRIVATE(name)
-#define CCTK_LOOP3_INTERIOR(name, i,j,k, \
- iblo,jblo,kblo, ibhi,jbhi,kbhi) \
- CCTK_LOOP3(name, \
- i,j,k, \
- (iblo),(jblo),(kblo), \
- CCTK_LSSH(0,1)-(ibhi), \
- CCTK_LSSH(0,2)-(jbhi), \
- CCTK_LSSH(0,3)-(kbhi), \
- cctk_lsh(1),cctk_lsh(2),cctk_lsh(3))
-#define CCTK_ENDLOOP3_INTERIOR(name) \
- CCTK_ENDLOOP3(name)
-
-#define CCTK_LOOP3_BOUNDARIES_DECLARE(name) \
- CCTK_LOOP3_DECLARE(name) && \
- integer :: lc_bmin(3), lc_bmax(3) && \
- integer :: lc_blo(3), lc_bhi(3) && \
- integer :: lc_dir, lc_face && \
- integer :: lc_d
+#ifdef CCODE
+
+/* LOOP */
+
+#define CCTK_LOOP3_NORMAL(name, \
+ i,j,k, \
+ ni,nj,nk, \
+ idir,jdir,kdir, \
+ imin,jmin,kmin, \
+ imax,jmax,kmax, \
+ ilsh,jlsh,klsh) \
+ CCTK_LOOP3STR_NORMAL(name, \
+ i,j,k, \
+ ni,nj,nk, \
+ (idir),(jdir),(kdir), \
+ (imin),(jmin),(kmin), \
+ (imax),(jmax),(kmax), \
+ (ilsh),(jlsh),(klsh), \
+ 1) \
+
+#define CCTK_ENDLOOP3_NORMAL(name) \
+ CCTK_ENDLOOP3STR_NORMAL(name) \
+
+#define CCTK_LOOP3STR_NORMAL(name, \
+ i,j,k, \
+ ni,nj,nk, \
+ idir,jdir,kdir, \
+ imin,jmin,kmin, \
+ imax,jmax,kmax, \
+ ilsh,jlsh,klsh, \
+ istr) \
+ do { \
+ typedef int cctki0_loop3_normal_##name; \
+ int const cctki0_idir = (idir); \
+ int const cctki0_jdir = (jdir); \
+ int const cctki0_kdir = (kdir); \
+ int const cctki0_imin = (imin); \
+ int const cctki0_jmin = (jmin); \
+ int const cctki0_kmin = (kmin); \
+ int const cctki0_imax = (imax); \
+ int const cctki0_jmax = (jmax); \
+ int const cctki0_kmax = (kmax); \
+ int const cctki0_istr CCTK_ATTRIBUTE_UNUSED = (istr); \
+ assert(cctki0_istr == 1); \
+ _Pragma("omp for") \
+ for (int k=cctki0_kmin; k<cctki0_kmax; ++k) { \
+ for (int j=cctki0_jmin; j<cctki0_jmax; ++j) { \
+ for (int i=cctki0_imin; i<cctki0_imax; ++i) { \
+ int const ni CCTK_ATTRIBUTE_UNUSED = cctki0_idir<0 ? i+1 : cctki0_idir==0 ? 0 : cctki0_imax-i; \
+ int const nj CCTK_ATTRIBUTE_UNUSED = cctki0_jdir<0 ? j+1 : cctki0_jdir==0 ? 0 : cctki0_jmax-j; \
+ int const nk CCTK_ATTRIBUTE_UNUSED = cctki0_kdir<0 ? k+1 : cctki0_kdir==0 ? 0 : cctki0_kmax-k; \
+ { \
+
+#define CCTK_ENDLOOP3STR_NORMAL(name) \
+ } \
+ } \
+ } \
+ } \
+ typedef cctki0_loop3_normal_##name cctki0_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+#define CCTK_LOOP3(name, \
+ i,j,k, \
+ imin,jmin,kmin, \
+ imax,jmax,kmax, \
+ ilsh,jlsh,klsh) \
+ CCTK_LOOP3STR(name, \
+ i,j,k, \
+ (imin),(jmin),(kmin), \
+ (imax),(jmax),(kmax), \
+ (ilsh),(jlsh),(klsh), \
+ 1) \
+
+#define CCTK_ENDLOOP3(name) \
+ CCTK_ENDLOOP3STR(name) \
+
+#define CCTK_LOOP3STR(name, \
+ i,j,k, \
+ imin,jmin,kmin, \
+ imax,jmax,kmax, \
+ ilsh,jlsh,klsh, \
+ istr) \
+ CCTK_LOOP3STR_NORMAL(name, \
+ i,j,k, \
+ cctki1_ni,cctki1_nj,cctki1_nk, \
+ 0,0,0, \
+ imin,jmin,kmin, \
+ imax,jmax,kmax, \
+ ilsh,jlsh,klsh, \
+ istr) \
+
+#define CCTK_ENDLOOP3STR(name) \
+ CCTK_ENDLOOP3STR_NORMAL(name) \
+
+
+
+/* LOOP_INTERIOR */
+
+#define CCTK_LOOP3_INTERIOR(name, cctkGH, \
+ i,j,k, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi) \
+ CCTK_LOOP3STR_INTERIOR(name, (cctkGH), \
+ i,j,k, \
+ (iblo),(jblo),(kblo), \
+ (ibhi),(jbhi),(kbhi), \
+ 1) \
+
+#define CCTK_ENDLOOP3_INTERIOR(name) \
+ CCTK_ENDLOOP3STR_INTERIOR(name) \
+
+#define CCTK_LOOP3STR_INTERIOR(name, cctkGH, \
+ i,j,k, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop3_interior_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 3) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP3_INTERIOR can only be used in 3 dimensions"); \
+ } \
+ CCTK_LOOP3STR(name##_interior, \
+ i,j,k, \
+ (iblo),(jblo),(kblo), \
+ cctki2_cctkGH->CCTK_LSSH(0,0)-(ibhi), \
+ cctki2_cctkGH->CCTK_LSSH(0,1)-(jbhi), \
+ cctki2_cctkGH->CCTK_LSSH(0,2)-(kbhi), \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_cctkGH->cctk_lsh[1], \
+ cctki2_cctkGH->cctk_lsh[2], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP3STR_INTERIOR(name) \
+ } CCTK_ENDLOOP3STR(name##_interior); \
+ typedef cctki2_loop3_interior_##name cctki2_ensure_proper_nesting; \
+ } while(0) \
+
+
+
+/* LOOP_BOUNDARIES */
+
+#define CCTK_LOOP3_BOUNDARIES(name, cctkGH, \
+ i,j,k, \
+ ni,nj,nk, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi, \
+ ibboxlo,jbboxlo,kbboxlo, \
+ ibboxhi,jbboxhi,kbboxhi) \
+ CCTK_LOOP3STR_BOUNDARIES(name, (cctkGH), \
+ i,j,k, \
+ ni,nj,nk, \
+ (iblo),(jblo),(kblo), \
+ (ibhi),(jbhi),(kbhi), \
+ (ibboxlo),(jbboxlo),(kbboxlo), \
+ (ibboxhi),(jbboxhi),(kbboxhi), \
+ 1) \
+
+#define CCTK_ENDLOOP3_BOUNDARIES(name) \
+ CCTK_ENDLOOP3STR_BOUNDARIES(name) \
+
+#define CCTK_LOOP3STR_BOUNDARIES(name, cctkGH, \
+ i,j,k, \
+ ni,nj,nk, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi, \
+ ibboxlo,jbboxlo,kbboxlo, \
+ ibboxhi,jbboxhi,kbboxhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop3_boundaries_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 3) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP3_BOUNDARIES can only be used in 3 dimensions"); \
+ } \
+ int const cctki2_blo[] = { (iblo),(jblo),(kblo) }; \
+ int const cctki2_bhi[] = { (ibhi),(jbhi),(kbhi) }; \
+ int const cctki2_bbox[] = { (ibboxlo), (ibboxhi),(jbboxlo), (jbboxhi),(kbboxlo), (kbboxhi) }; \
+ int const cctki2_lssh[] = { cctki2_cctkGH->CCTK_LSSH(0,0),cctki2_cctkGH->CCTK_LSSH(0,1),cctki2_cctkGH->CCTK_LSSH(0,2) }; \
+ int const cctki2_istr1 CCTK_ATTRIBUTE_UNUSED = (istr); \
+ /* Loop over all faces, edges, and corners */ \
+ for (int cctki2_kdir=-1; cctki2_kdir<=+1; ++cctki2_kdir) { \
+ for (int cctki2_jdir=-1; cctki2_jdir<=+1; ++cctki2_jdir) { \
+ for (int cctki2_idir=-1; cctki2_idir<=+1; ++cctki2_idir) { \
+ int cctki2_any_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 0) || (cctki2_idir==+1 ? cctki2_bbox[1] : 0)|| \
+ (cctki2_jdir==-1 ? cctki2_bbox[2] : 0) || (cctki2_jdir==+1 ? cctki2_bbox[3] : 0)|| \
+ (cctki2_kdir==-1 ? cctki2_bbox[4] : 0) || (cctki2_kdir==+1 ? cctki2_bbox[5] : 0); \
+ if (cctki2_any_bbox) { \
+ int const cctki2_bmin[] = { \
+ cctki2_idir==-1 ? 0 : cctki2_idir==0 ? cctki2_blo[0] : cctki2_lssh[0] - cctki2_bhi[0], \
+ cctki2_jdir==-1 ? 0 : cctki2_jdir==0 ? cctki2_blo[1] : cctki2_lssh[1] - cctki2_bhi[1], \
+ cctki2_kdir==-1 ? 0 : cctki2_kdir==0 ? cctki2_blo[2] : cctki2_lssh[2] - cctki2_bhi[2], \
+ }; \
+ int const cctki2_bmax[] = { \
+ cctki2_idir==-1 ? cctki2_blo[0] : cctki2_idir==0 ? cctki2_lssh[0] - cctki2_bhi[0] : cctki2_lssh[0], \
+ cctki2_jdir==-1 ? cctki2_blo[1] : cctki2_jdir==0 ? cctki2_lssh[1] - cctki2_bhi[1] : cctki2_lssh[1], \
+ cctki2_kdir==-1 ? cctki2_blo[2] : cctki2_kdir==0 ? cctki2_lssh[2] - cctki2_bhi[2] : cctki2_lssh[2], \
+ }; \
+ CCTK_LOOP3STR_NORMAL(name##_boundaries, \
+ i,j,k, \
+ ni,nj,nk, \
+ cctki2_idir,cctki2_jdir,cctki2_kdir, \
+ cctki2_bmin[0],cctki2_bmin[1],cctki2_bmin[2], \
+ cctki2_bmax[0],cctki2_bmax[1],cctki2_bmax[2], \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_cctkGH->cctk_lsh[1], \
+ cctki2_cctkGH->cctk_lsh[2], \
+ cctki2_istr1) { \
+
+#define CCTK_ENDLOOP3STR_BOUNDARIES(name) \
+ } CCTK_ENDLOOP3STR_NORMAL(name##_boundaries); \
+ } /* if bbox */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ typedef cctki2_loop3_boundaries_##name cctki2_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INTBOUNDARIES */
+
+#define CCTK_LOOP3_INTBOUNDARIES(name, cctkGH, \
+ i,j,k, \
+ ni,nj,nk, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi, \
+ ibboxlo,jbboxlo,kbboxlo, \
+ ibboxhi,jbboxhi,kbboxhi) \
+ CCTK_LOOP3STR_INTBOUNDARIES(name, (cctkGH), \
+ i,j,k, \
+ ni,nj,nk, \
+ (iblo),(jblo),(kblo), \
+ (ibhi),(jbhi),(kbhi), \
+ (ibboxlo),(jbboxlo),(kbboxlo), \
+ (ibboxhi),(jbboxhi),(kbboxhi), \
+ 1) \
+
+#define CCTK_ENDLOOP3_INTBOUNDARIES(name) \
+ CCTK_ENDLOOP3STR_INTBOUNDARIES(name) \
+
+#define CCTK_LOOP3STR_INTBOUNDARIES(name, cctkGH, \
+ i,j,k, \
+ ni,nj,nk, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi, \
+ ibboxlo,jbboxlo,kbboxlo, \
+ ibboxhi,jbboxhi,kbboxhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop3_intboundaries_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 3) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP3_INTBOUNDARIES can only be used in 3 dimensions"); \
+ } \
+ int const cctki2_blo[] = { (iblo),(jblo),(kblo) }; \
+ int const cctki2_bhi[] = { (ibhi),(jbhi),(kbhi) }; \
+ int const cctki2_bbox[] = { (ibboxlo), (ibboxhi),(jbboxlo), (jbboxhi),(kbboxlo), (kbboxhi) }; \
+ int const cctki2_lssh[] = { cctki2_cctkGH->CCTK_LSSH(0,0),cctki2_cctkGH->CCTK_LSSH(0,1),cctki2_cctkGH->CCTK_LSSH(0,2) }; \
+ int const cctki2_istr1 CCTK_ATTRIBUTE_UNUSED = (istr); \
+ /* Loop over all faces, edges, and corners */ \
+ for (int cctki2_kdir=-1; cctki2_kdir<=+1; ++cctki2_kdir) { \
+ for (int cctki2_jdir=-1; cctki2_jdir<=+1; ++cctki2_jdir) { \
+ for (int cctki2_idir=-1; cctki2_idir<=+1; ++cctki2_idir) { \
+ int cctki2_any_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 0) || (cctki2_idir==+1 ? cctki2_bbox[1] : 0)|| \
+ (cctki2_jdir==-1 ? cctki2_bbox[2] : 0) || (cctki2_jdir==+1 ? cctki2_bbox[3] : 0)|| \
+ (cctki2_kdir==-1 ? cctki2_bbox[4] : 0) || (cctki2_kdir==+1 ? cctki2_bbox[5] : 0); \
+ int cctki2_all_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 1) && (cctki2_idir==+1 ? cctki2_bbox[1] : 1)&& \
+ (cctki2_jdir==-1 ? cctki2_bbox[2] : 1) && (cctki2_jdir==+1 ? cctki2_bbox[3] : 1)&& \
+ (cctki2_kdir==-1 ? cctki2_bbox[4] : 1) && (cctki2_kdir==+1 ? cctki2_bbox[5] : 1); \
+ if (cctki2_all_bbox && cctki2_any_bbox) { \
+ int const cctki2_bmin[] = { \
+ cctki2_idir==-1 ? 0 : cctki2_idir==0 ? cctki2_blo[0] : cctki2_lssh[0] - cctki2_bhi[0], \
+ cctki2_jdir==-1 ? 0 : cctki2_jdir==0 ? cctki2_blo[1] : cctki2_lssh[1] - cctki2_bhi[1], \
+ cctki2_kdir==-1 ? 0 : cctki2_kdir==0 ? cctki2_blo[2] : cctki2_lssh[2] - cctki2_bhi[2], \
+ }; \
+ int const cctki2_bmax[] = { \
+ cctki2_idir==-1 ? cctki2_blo[0] : cctki2_idir==0 ? cctki2_lssh[0] - cctki2_bhi[0] : cctki2_lssh[0], \
+ cctki2_jdir==-1 ? cctki2_blo[1] : cctki2_jdir==0 ? cctki2_lssh[1] - cctki2_bhi[1] : cctki2_lssh[1], \
+ cctki2_kdir==-1 ? cctki2_blo[2] : cctki2_kdir==0 ? cctki2_lssh[2] - cctki2_bhi[2] : cctki2_lssh[2], \
+ }; \
+ CCTK_LOOP3STR_NORMAL(name##_intboundaries, \
+ i,j,k, \
+ ni,nj,nk, \
+ cctki2_idir,cctki2_jdir,cctki2_kdir, \
+ cctki2_bmin[0],cctki2_bmin[1],cctki2_bmin[2], \
+ cctki2_bmax[0],cctki2_bmax[1],cctki2_bmax[2], \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_cctkGH->cctk_lsh[1], \
+ cctki2_cctkGH->cctk_lsh[2], \
+ cctki2_istr1) { \
+
+#define CCTK_ENDLOOP3STR_INTBOUNDARIES(name) \
+ } CCTK_ENDLOOP3STR_NORMAL(name##_intboundaries); \
+ } /* if bbox */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ typedef cctki2_loop3_intboundaries_##name cctki2_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_ALL */
+
+#define CCTK_LOOP3_ALL(name, cctkGH, \
+ i,j,k) \
+ CCTK_LOOP3STR_ALL(name, (cctkGH), \
+ i,j,k, \
+ 1) \
+
+#define CCTK_ENDLOOP3_ALL(name) \
+ CCTK_ENDLOOP3STR_ALL(name) \
+
+#define CCTK_LOOP3STR_ALL(name, cctkGH, \
+ i,j,k, \
+ istr) \
+ do { \
+ typedef int cctki3_loop3_all_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 3) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP3_ALL can only be used in 3 dimensions"); \
+ } \
+ CCTK_LOOP3STR(name##_all, \
+ i,j,k, \
+ 0,0,0, \
+ cctki3_cctkGH->CCTK_LSSH(0,0), \
+ cctki3_cctkGH->CCTK_LSSH(0,1), \
+ cctki3_cctkGH->CCTK_LSSH(0,2), \
+ cctki3_cctkGH->cctk_lsh[0], \
+ cctki3_cctkGH->cctk_lsh[1], \
+ cctki3_cctkGH->cctk_lsh[2], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP3STR_ALL(name) \
+ } CCTK_ENDLOOP3STR(name##_all); \
+ typedef cctki3_loop3_all_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INT */
+
+#define CCTK_LOOP3_INT(name, cctkGH, \
+ i,j,k) \
+ CCTK_LOOP3STR_INT(name, (cctkGH), \
+ i,j,k, \
+ 1) \
+
+#define CCTK_ENDLOOP3_INT(name) \
+ CCTK_ENDLOOP3STR_INT(name) \
+
+#define CCTK_LOOP3STR_INT(name, cctkGH, \
+ i,j,k, \
+ istr) \
+ do { \
+ typedef int cctki3_loop3_int_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 3) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP3_INT can only be used in 3 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [6]; \
+ CCTK_INT cctki3_is_ghostbnd[6]; \
+ CCTK_INT cctki3_is_symbnd [6]; \
+ CCTK_INT cctki3_is_physbnd [6]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 6, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP3STR_INTERIOR(name##_int, \
+ cctki3_cctkGH, \
+ i,j,k, \
+ cctki3_bndsize[0],cctki3_bndsize[2],cctki3_bndsize[4], \
+ cctki3_bndsize[1],cctki3_bndsize[3],cctki3_bndsize[5], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP3STR_INT(name) \
+ } CCTK_ENDLOOP3STR_INTERIOR(name##_int); \
+ typedef cctki3_loop3_int_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_BND */
+
+#define CCTK_LOOP3_BND(name, cctkGH, \
+ i,j,k, \
+ ni,nj,nk) \
+ CCTK_LOOP3STR_BND(name, (cctkGH), \
+ i,j,k, \
+ ni,nj,nk, \
+ 1) \
+
+#define CCTK_ENDLOOP3_BND(name) \
+ CCTK_ENDLOOP3STR_BND(name) \
+
+#define CCTK_LOOP3STR_BND(name, cctkGH, \
+ i,j,k, \
+ ni,nj,nk, \
+ istr) \
+ do { \
+ typedef int cctki3_loop3_bnd_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 3) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP3_BND can only be used in 3 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [6]; \
+ CCTK_INT cctki3_is_ghostbnd[6]; \
+ CCTK_INT cctki3_is_symbnd [6]; \
+ CCTK_INT cctki3_is_physbnd [6]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize, cctki3_is_physbnd)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 6, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP3STR_BOUNDARIES(name##_bnd, \
+ cctki3_cctkGH, \
+ i,j,k, \
+ ni,nj,nk, \
+ cctki3_bndsize[0],cctki3_bndsize[2],cctki3_bndsize[4], \
+ cctki3_bndsize[1],cctki3_bndsize[3],cctki3_bndsize[5], \
+ cctki3_is_physbnd[0],cctki3_is_physbnd[2],cctki3_is_physbnd[4], \
+ cctki3_is_physbnd[1],cctki3_is_physbnd[3],cctki3_is_physbnd[5], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP3STR_BND(name) \
+ } CCTK_ENDLOOP3STR_BOUNDARIES(name##_bnd); \
+ typedef cctki3_loop3_bnd_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INTBND */
+
+#define CCTK_LOOP3_INTBND(name, cctkGH, \
+ i,j,k, \
+ ni,nj,nk) \
+ CCTK_LOOP3STR_INTBND(name, (cctkGH), \
+ i,j,k, \
+ ni,nj,nk, \
+ 1) \
+
+#define CCTK_ENDLOOP3_INTBND(name) \
+ CCTK_ENDLOOP3STR_INTBND(name) \
+
+#define CCTK_LOOP3STR_INTBND(name, cctkGH, \
+ i,j,k, \
+ ni,nj,nk, \
+ istr) \
+ do { \
+ typedef int cctki3_loop3_intbnd_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 3) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP3_INTBND can only be used in 3 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [6]; \
+ CCTK_INT cctki3_is_ghostbnd[6]; \
+ CCTK_INT cctki3_is_symbnd [6]; \
+ CCTK_INT cctki3_is_physbnd [6]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize, cctki3_is_physbnd)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 6, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP3STR_INTBOUNDARIES(name##_intbnd, \
+ cctki3_cctkGH, \
+ i,j,k, \
+ ni,nj,nk, \
+ cctki3_bndsize[0],cctki3_bndsize[2],cctki3_bndsize[4], \
+ cctki3_bndsize[1],cctki3_bndsize[3],cctki3_bndsize[5], \
+ cctki3_is_physbnd[0],cctki3_is_physbnd[2],cctki3_is_physbnd[4], \
+ cctki3_is_physbnd[1],cctki3_is_physbnd[3],cctki3_is_physbnd[5], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP3STR_INTBND(name) \
+ } CCTK_ENDLOOP3STR_INTBOUNDARIES(name##_intbnd); \
+ typedef cctki3_loop3_intbnd_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+#endif /* #ifdef CCODE */
+
+
+
+#ifdef FCODE
+
+/* LOOP */
+
+#define CCTK_LOOP3_DECLARE(name) \
+ && integer :: name/**/_imin,name/**/_jmin,name/**/_kmin \
+ && integer :: name/**/_imax,name/**/_jmax,name/**/_kmax \
+ && integer :: name/**/_istr \
+
+#define CCTK_LOOP3_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP3(name, \
+ i,j,k, \
+ imin,jmin,kmin, \
+ imax,jmax,kmax, \
+ ilsh,jlsh,klsh) \
+ CCTK_LOOP3STR(name, \
+ i,j,k, \
+ imin,jmin,kmin, \
+ imax,jmax,kmax, \
+ ilsh,jlsh,klsh, \
+ 1) \
+
+#define CCTK_LOOP3STR(name, \
+ i,j,k, \
+ imin,jmin,kmin, \
+ imax,jmax,kmax, \
+ ilsh,jlsh,klsh, \
+ istr) \
+ && name/**/_imin = imin \
+ && name/**/_jmin = jmin \
+ && name/**/_kmin = kmin \
+ && name/**/_imax = imax \
+ && name/**/_jmax = jmax \
+ && name/**/_kmax = kmax \
+ && name/**/_istr = istr \
+ && do k = name/**/_kmin, name/**/_kmax \
+ && do j = name/**/_jmin, name/**/_jmax \
+ && do i = name/**/_imin, name/**/_imax \
+
+#define CCTK_ENDLOOP3(name) \
+ CCTK_ENDLOOP3STR(name) \
+
+#define CCTK_ENDLOOP3STR(name) \
+ && end do \
+ && end do \
+ && end do \
+
+
+
+/* LOOP_ALL */
+
+#define CCTK_LOOP3_ALL_DECLARE(name) \
+ CCTK_LOOP3_DECLARE(name) \
+
+#define CCTK_LOOP3_ALL_OMP_PRIVATE(name) \
+ CCTK_LOOP3_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP3_ALL(name, \
+ i,j,k) \
+ CCTK_LOOP3STR_ALL(name, \
+ i,j,k, \
+ 1) \
+
+#define CCTK_LOOP3STR_ALL(name, \
+ i,j,k, \
+ istr) \
+ CCTK_LOOP3STR(name, \
+ i,j,k, \
+ 1,1,1, \
+ CCTK_LSSH(0,1),CCTK_LSSH(0,2),CCTK_LSSH(0,3), \
+ cctk_lsh(1),cctk_lsh(2),cctk_lsh(3), \
+ istr) \
+
+#define CCTK_ENDLOOP3_ALL(name) \
+ CCTK_ENDLOOP3STR_ALL(name) \
+
+#define CCTK_ENDLOOP3STR_ALL(name) \
+ CCTK_ENDLOOP3(name) \
+
+
+
+/* LOOP_INTERIOR */
+
+#define CCTK_LOOP3_INTERIOR_DECLARE(name) \
+ CCTK_LOOP3_DECLARE(name) \
+
+#define CCTK_LOOP3_INTERIOR_OMP_PRIVATE(name) \
+ CCTK_LOOP3_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP3_INTERIOR(name, \
+ i,j,k, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi) \
+ CCTK_LOOP3STR_INTERIOR(name, \
+ i,j,k, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi, \
+ 1) \
+
+#define CCTK_LOOP3STR_INTERIOR(name, \
+ i,j,k, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi, \
+ istr) \
+ CCTK_LOOP3STR(name, \
+ i,j,k, \
+ (iblo),(jblo),(kblo), \
+ CCTK_LSSH(0,1)-(ibhi), \
+ CCTK_LSSH(0,2)-(jbhi), \
+ CCTK_LSSH(0,3)-(kbhi), \
+ cctk_lsh(1),cctk_lsh(2),cctk_lsh(3), \
+ istr) \
+
+#define CCTK_ENDLOOP3_INTERIOR(name) \
+ CCTK_ENDLOOP3STR_INTERIOR(name) \
+
+#define CCTK_ENDLOOP3STR_INTERIOR(name) \
+ CCTK_ENDLOOP3(name) \
+
+
+
+/* LOOP_BOUNDARIES */
+
+#define CCTK_LOOP3_BOUNDARIES_DECLARE(name) \
+ CCTK_LOOP3_DECLARE(name) \
+ && integer :: lc_bmin(3), lc_bmax(3) \
+ && integer :: lc_blo(3), lc_bhi(3) \
+ && integer :: lc_istr \
+ && integer :: lc_dir, lc_face \
+ && integer :: lc_d \
+
#define CCTK_LOOP3_BOUNDARIES_OMP_PRIVATE(name) \
- CCTK_LOOP3_OMP_PRIVATE(name)
-#define CCTK_LOOP3_BOUNDARIES(name, i,j,k, \
- iblo,jblo,kblo, ibhi,jbhi,kbhi) \
- lc_blo = (/ (iblo),(jblo),(kblo) /) && \
- lc_bhi = (/ (ibhi),(jbhi),(kbhi) /) && \
- do lc_dir=1,3 && \
- do lc_face=1,2 && \
- do lc_d=1,3 && \
- lc_bmin(lc_d) = 0 && \
- lc_bmax(lc_d) = CCTK_LSSH(0,lc_d) && \
- if (lc_d<lc_dir) then && \
- lc_bmin(lc_d) = lc_bmin(lc_d)+lc_blo(lc_d) && \
- lc_bmax(lc_d) = lc_bmax(lc_d)-lc_bhi(lc_d) && \
- end if && \
- end do && \
- if (lc_face==0) then && \
- lc_bmax(lc_dir) = lc_bmin(lc_dir)+lc_blo(lc_dir) && \
- else && \
- lc_bmin(lc_dir) = lc_bmax(lc_dir)-lc_bhi(lc_dir) && \
- end if && \
- CCTK_LOOP3(name, \
- i,j,k, \
- lc_bmin(1),lc_bmin(2),lc_bmin(3), \
- lc_bmax(1),lc_bmax(2),lc_bmax(3), \
- cctk_lsh(1),cctk_lsh(2),cctk_lsh(3))
-#define CCTK_ENDLOOP3_BOUNDARIES(name) \
- CCTK_ENDLOOP3(name) && \
- end do /* face */ && \
- end do /* dir */
-
-
-
-#endif
+ CCTK_LOOP3_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP3_BOUNDARIES(name, \
+ i,j,k, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi) \
+ CCTK_LOOP3STR_BOUNDARIES(name, \
+ i,j,k, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi, \
+ 1) \
+
+#define CCTK_LOOP3STR_BOUNDARIES(name, \
+ i,j,k, \
+ iblo,jblo,kblo, \
+ ibhi,jbhi,kbhi, \
+ istr) \
+ && lc_blo = (/ iblo,jblo,kblo /) \
+ && lc_bhi = (/ ibhi,jbhi,kbhi /) \
+ && lc_istr = istr \
+ && do lc_dir=1,3 \
+ && do lc_face=1,2 \
+ && do lc_d=1,3 \
+ && lc_bmin(lc_d) = 1 \
+ && lc_bmax(lc_d) = CCTK_LSSH(0,lc_d) \
+ && if (lc_d<lc_dir) then \
+ && lc_bmin(lc_d) = lc_bmin(lc_d)+lc_blo(lc_d) \
+ && lc_bmax(lc_d) = lc_bmax(lc_d)-lc_bhi(lc_d) \
+ && end if \
+ && end do \
+ && if (lc_face==1) then \
+ && lc_bmax(lc_dir) = lc_bmin(lc_dir)+lc_blo(lc_dir) \
+ && else \
+ && lc_bmin(lc_dir) = lc_bmax(lc_dir)-lc_bhi(lc_dir) \
+ && end if \
+ CCTK_LOOP3STR(name, \
+ i,j,k, \
+ lc_bmin(1),lc_bmin(2),lc_bmin(3), \
+ lc_bmax(1),lc_bmax(2),lc_bmax(3), \
+ cctk_lsh(1),cctk_lsh(2),cctk_lsh(3), \
+ lc_istr) \
+
+#define CCTK_ENDLOOP3_BOUNDARIES(name) \
+ CCTK_ENDLOOP3STR_BOUNDARIES(name) \
+
+#define CCTK_ENDLOOP3STR_BOUNDARIES(name) \
+ CCTK_ENDLOOP3(name) \
+ && end do /* face */ \
+ && end do /* dir */ \
+
+#endif /* #ifdef FCODE */
+
+
+
+/* 4D */
+
+#ifdef CCODE
+
+/* LOOP */
+
+#define CCTK_LOOP4_NORMAL(name, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ idir,jdir,kdir,ldir, \
+ imin,jmin,kmin,lmin, \
+ imax,jmax,kmax,lmax, \
+ ilsh,jlsh,klsh,llsh) \
+ CCTK_LOOP4STR_NORMAL(name, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ (idir),(jdir),(kdir),(ldir), \
+ (imin),(jmin),(kmin),(lmin), \
+ (imax),(jmax),(kmax),(lmax), \
+ (ilsh),(jlsh),(klsh),(llsh), \
+ 1) \
+
+#define CCTK_ENDLOOP4_NORMAL(name) \
+ CCTK_ENDLOOP4STR_NORMAL(name) \
+
+#define CCTK_LOOP4STR_NORMAL(name, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ idir,jdir,kdir,ldir, \
+ imin,jmin,kmin,lmin, \
+ imax,jmax,kmax,lmax, \
+ ilsh,jlsh,klsh,llsh, \
+ istr) \
+ do { \
+ typedef int cctki0_loop4_normal_##name; \
+ int const cctki0_idir = (idir); \
+ int const cctki0_jdir = (jdir); \
+ int const cctki0_kdir = (kdir); \
+ int const cctki0_ldir = (ldir); \
+ int const cctki0_imin = (imin); \
+ int const cctki0_jmin = (jmin); \
+ int const cctki0_kmin = (kmin); \
+ int const cctki0_lmin = (lmin); \
+ int const cctki0_imax = (imax); \
+ int const cctki0_jmax = (jmax); \
+ int const cctki0_kmax = (kmax); \
+ int const cctki0_lmax = (lmax); \
+ int const cctki0_istr CCTK_ATTRIBUTE_UNUSED = (istr); \
+ assert(cctki0_istr == 1); \
+ _Pragma("omp for") \
+ for (int l=cctki0_lmin; l<cctki0_lmax; ++l) { \
+ for (int k=cctki0_kmin; k<cctki0_kmax; ++k) { \
+ for (int j=cctki0_jmin; j<cctki0_jmax; ++j) { \
+ for (int i=cctki0_imin; i<cctki0_imax; ++i) { \
+ int const ni CCTK_ATTRIBUTE_UNUSED = cctki0_idir<0 ? i+1 : cctki0_idir==0 ? 0 : cctki0_imax-i; \
+ int const nj CCTK_ATTRIBUTE_UNUSED = cctki0_jdir<0 ? j+1 : cctki0_jdir==0 ? 0 : cctki0_jmax-j; \
+ int const nk CCTK_ATTRIBUTE_UNUSED = cctki0_kdir<0 ? k+1 : cctki0_kdir==0 ? 0 : cctki0_kmax-k; \
+ int const nl CCTK_ATTRIBUTE_UNUSED = cctki0_ldir<0 ? l+1 : cctki0_ldir==0 ? 0 : cctki0_lmax-l; \
+ { \
+
+#define CCTK_ENDLOOP4STR_NORMAL(name) \
+ } \
+ } \
+ } \
+ } \
+ } \
+ typedef cctki0_loop4_normal_##name cctki0_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+#define CCTK_LOOP4(name, \
+ i,j,k,l, \
+ imin,jmin,kmin,lmin, \
+ imax,jmax,kmax,lmax, \
+ ilsh,jlsh,klsh,llsh) \
+ CCTK_LOOP4STR(name, \
+ i,j,k,l, \
+ (imin),(jmin),(kmin),(lmin), \
+ (imax),(jmax),(kmax),(lmax), \
+ (ilsh),(jlsh),(klsh),(llsh), \
+ 1) \
+
+#define CCTK_ENDLOOP4(name) \
+ CCTK_ENDLOOP4STR(name) \
+
+#define CCTK_LOOP4STR(name, \
+ i,j,k,l, \
+ imin,jmin,kmin,lmin, \
+ imax,jmax,kmax,lmax, \
+ ilsh,jlsh,klsh,llsh, \
+ istr) \
+ CCTK_LOOP4STR_NORMAL(name, \
+ i,j,k,l, \
+ cctki1_ni,cctki1_nj,cctki1_nk,cctki1_nl, \
+ 0,0,0,0, \
+ imin,jmin,kmin,lmin, \
+ imax,jmax,kmax,lmax, \
+ ilsh,jlsh,klsh,llsh, \
+ istr) \
+
+#define CCTK_ENDLOOP4STR(name) \
+ CCTK_ENDLOOP4STR_NORMAL(name) \
+
+
+
+/* LOOP_INTERIOR */
+
+#define CCTK_LOOP4_INTERIOR(name, cctkGH, \
+ i,j,k,l, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi) \
+ CCTK_LOOP4STR_INTERIOR(name, (cctkGH), \
+ i,j,k,l, \
+ (iblo),(jblo),(kblo),(lblo), \
+ (ibhi),(jbhi),(kbhi),(lbhi), \
+ 1) \
+
+#define CCTK_ENDLOOP4_INTERIOR(name) \
+ CCTK_ENDLOOP4STR_INTERIOR(name) \
+
+#define CCTK_LOOP4STR_INTERIOR(name, cctkGH, \
+ i,j,k,l, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop4_interior_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 4) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP4_INTERIOR can only be used in 4 dimensions"); \
+ } \
+ CCTK_LOOP4STR(name##_interior, \
+ i,j,k,l, \
+ (iblo),(jblo),(kblo),(lblo), \
+ cctki2_cctkGH->CCTK_LSSH(0,0)-(ibhi), \
+ cctki2_cctkGH->CCTK_LSSH(0,1)-(jbhi), \
+ cctki2_cctkGH->CCTK_LSSH(0,2)-(kbhi), \
+ cctki2_cctkGH->CCTK_LSSH(0,3)-(lbhi), \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_cctkGH->cctk_lsh[1], \
+ cctki2_cctkGH->cctk_lsh[2], \
+ cctki2_cctkGH->cctk_lsh[3], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP4STR_INTERIOR(name) \
+ } CCTK_ENDLOOP4STR(name##_interior); \
+ typedef cctki2_loop4_interior_##name cctki2_ensure_proper_nesting; \
+ } while(0) \
+
+
+
+/* LOOP_BOUNDARIES */
+
+#define CCTK_LOOP4_BOUNDARIES(name, cctkGH, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi, \
+ ibboxlo,jbboxlo,kbboxlo,lbboxlo, \
+ ibboxhi,jbboxhi,kbboxhi,lbboxhi) \
+ CCTK_LOOP4STR_BOUNDARIES(name, (cctkGH), \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ (iblo),(jblo),(kblo),(lblo), \
+ (ibhi),(jbhi),(kbhi),(lbhi), \
+ (ibboxlo),(jbboxlo),(kbboxlo),(lbboxlo), \
+ (ibboxhi),(jbboxhi),(kbboxhi),(lbboxhi), \
+ 1) \
+
+#define CCTK_ENDLOOP4_BOUNDARIES(name) \
+ CCTK_ENDLOOP4STR_BOUNDARIES(name) \
+
+#define CCTK_LOOP4STR_BOUNDARIES(name, cctkGH, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi, \
+ ibboxlo,jbboxlo,kbboxlo,lbboxlo, \
+ ibboxhi,jbboxhi,kbboxhi,lbboxhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop4_boundaries_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 4) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP4_BOUNDARIES can only be used in 4 dimensions"); \
+ } \
+ int const cctki2_blo[] = { (iblo),(jblo),(kblo),(lblo) }; \
+ int const cctki2_bhi[] = { (ibhi),(jbhi),(kbhi),(lbhi) }; \
+ int const cctki2_bbox[] = { (ibboxlo), (ibboxhi),(jbboxlo), (jbboxhi),(kbboxlo), (kbboxhi),(lbboxlo), (lbboxhi) }; \
+ int const cctki2_lssh[] = { cctki2_cctkGH->CCTK_LSSH(0,0),cctki2_cctkGH->CCTK_LSSH(0,1),cctki2_cctkGH->CCTK_LSSH(0,2),cctki2_cctkGH->CCTK_LSSH(0,3) }; \
+ int const cctki2_istr1 CCTK_ATTRIBUTE_UNUSED = (istr); \
+ /* Loop over all faces, edges, and corners */ \
+ for (int cctki2_ldir=-1; cctki2_ldir<=+1; ++cctki2_ldir) { \
+ for (int cctki2_kdir=-1; cctki2_kdir<=+1; ++cctki2_kdir) { \
+ for (int cctki2_jdir=-1; cctki2_jdir<=+1; ++cctki2_jdir) { \
+ for (int cctki2_idir=-1; cctki2_idir<=+1; ++cctki2_idir) { \
+ int cctki2_any_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 0) || (cctki2_idir==+1 ? cctki2_bbox[1] : 0)|| \
+ (cctki2_jdir==-1 ? cctki2_bbox[2] : 0) || (cctki2_jdir==+1 ? cctki2_bbox[3] : 0)|| \
+ (cctki2_kdir==-1 ? cctki2_bbox[4] : 0) || (cctki2_kdir==+1 ? cctki2_bbox[5] : 0)|| \
+ (cctki2_ldir==-1 ? cctki2_bbox[6] : 0) || (cctki2_ldir==+1 ? cctki2_bbox[7] : 0); \
+ if (cctki2_any_bbox) { \
+ int const cctki2_bmin[] = { \
+ cctki2_idir==-1 ? 0 : cctki2_idir==0 ? cctki2_blo[0] : cctki2_lssh[0] - cctki2_bhi[0], \
+ cctki2_jdir==-1 ? 0 : cctki2_jdir==0 ? cctki2_blo[1] : cctki2_lssh[1] - cctki2_bhi[1], \
+ cctki2_kdir==-1 ? 0 : cctki2_kdir==0 ? cctki2_blo[2] : cctki2_lssh[2] - cctki2_bhi[2], \
+ cctki2_ldir==-1 ? 0 : cctki2_ldir==0 ? cctki2_blo[3] : cctki2_lssh[3] - cctki2_bhi[3], \
+ }; \
+ int const cctki2_bmax[] = { \
+ cctki2_idir==-1 ? cctki2_blo[0] : cctki2_idir==0 ? cctki2_lssh[0] - cctki2_bhi[0] : cctki2_lssh[0], \
+ cctki2_jdir==-1 ? cctki2_blo[1] : cctki2_jdir==0 ? cctki2_lssh[1] - cctki2_bhi[1] : cctki2_lssh[1], \
+ cctki2_kdir==-1 ? cctki2_blo[2] : cctki2_kdir==0 ? cctki2_lssh[2] - cctki2_bhi[2] : cctki2_lssh[2], \
+ cctki2_ldir==-1 ? cctki2_blo[3] : cctki2_ldir==0 ? cctki2_lssh[3] - cctki2_bhi[3] : cctki2_lssh[3], \
+ }; \
+ CCTK_LOOP4STR_NORMAL(name##_boundaries, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ cctki2_idir,cctki2_jdir,cctki2_kdir,cctki2_ldir, \
+ cctki2_bmin[0],cctki2_bmin[1],cctki2_bmin[2],cctki2_bmin[3], \
+ cctki2_bmax[0],cctki2_bmax[1],cctki2_bmax[2],cctki2_bmax[3], \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_cctkGH->cctk_lsh[1], \
+ cctki2_cctkGH->cctk_lsh[2], \
+ cctki2_cctkGH->cctk_lsh[3], \
+ cctki2_istr1) { \
+
+#define CCTK_ENDLOOP4STR_BOUNDARIES(name) \
+ } CCTK_ENDLOOP4STR_NORMAL(name##_boundaries); \
+ } /* if bbox */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ typedef cctki2_loop4_boundaries_##name cctki2_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INTBOUNDARIES */
+
+#define CCTK_LOOP4_INTBOUNDARIES(name, cctkGH, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi, \
+ ibboxlo,jbboxlo,kbboxlo,lbboxlo, \
+ ibboxhi,jbboxhi,kbboxhi,lbboxhi) \
+ CCTK_LOOP4STR_INTBOUNDARIES(name, (cctkGH), \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ (iblo),(jblo),(kblo),(lblo), \
+ (ibhi),(jbhi),(kbhi),(lbhi), \
+ (ibboxlo),(jbboxlo),(kbboxlo),(lbboxlo), \
+ (ibboxhi),(jbboxhi),(kbboxhi),(lbboxhi), \
+ 1) \
+
+#define CCTK_ENDLOOP4_INTBOUNDARIES(name) \
+ CCTK_ENDLOOP4STR_INTBOUNDARIES(name) \
+
+#define CCTK_LOOP4STR_INTBOUNDARIES(name, cctkGH, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi, \
+ ibboxlo,jbboxlo,kbboxlo,lbboxlo, \
+ ibboxhi,jbboxhi,kbboxhi,lbboxhi, \
+ istr) \
+ do { \
+ typedef int cctki2_loop4_intboundaries_##name; \
+ cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH); \
+ if (cctki2_cctkGH->cctk_dim != 4) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP4_INTBOUNDARIES can only be used in 4 dimensions"); \
+ } \
+ int const cctki2_blo[] = { (iblo),(jblo),(kblo),(lblo) }; \
+ int const cctki2_bhi[] = { (ibhi),(jbhi),(kbhi),(lbhi) }; \
+ int const cctki2_bbox[] = { (ibboxlo), (ibboxhi),(jbboxlo), (jbboxhi),(kbboxlo), (kbboxhi),(lbboxlo), (lbboxhi) }; \
+ int const cctki2_lssh[] = { cctki2_cctkGH->CCTK_LSSH(0,0),cctki2_cctkGH->CCTK_LSSH(0,1),cctki2_cctkGH->CCTK_LSSH(0,2),cctki2_cctkGH->CCTK_LSSH(0,3) }; \
+ int const cctki2_istr1 CCTK_ATTRIBUTE_UNUSED = (istr); \
+ /* Loop over all faces, edges, and corners */ \
+ for (int cctki2_ldir=-1; cctki2_ldir<=+1; ++cctki2_ldir) { \
+ for (int cctki2_kdir=-1; cctki2_kdir<=+1; ++cctki2_kdir) { \
+ for (int cctki2_jdir=-1; cctki2_jdir<=+1; ++cctki2_jdir) { \
+ for (int cctki2_idir=-1; cctki2_idir<=+1; ++cctki2_idir) { \
+ int cctki2_any_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 0) || (cctki2_idir==+1 ? cctki2_bbox[1] : 0)|| \
+ (cctki2_jdir==-1 ? cctki2_bbox[2] : 0) || (cctki2_jdir==+1 ? cctki2_bbox[3] : 0)|| \
+ (cctki2_kdir==-1 ? cctki2_bbox[4] : 0) || (cctki2_kdir==+1 ? cctki2_bbox[5] : 0)|| \
+ (cctki2_ldir==-1 ? cctki2_bbox[6] : 0) || (cctki2_ldir==+1 ? cctki2_bbox[7] : 0); \
+ int cctki2_all_bbox = \
+ (cctki2_idir==-1 ? cctki2_bbox[0] : 1) && (cctki2_idir==+1 ? cctki2_bbox[1] : 1)&& \
+ (cctki2_jdir==-1 ? cctki2_bbox[2] : 1) && (cctki2_jdir==+1 ? cctki2_bbox[3] : 1)&& \
+ (cctki2_kdir==-1 ? cctki2_bbox[4] : 1) && (cctki2_kdir==+1 ? cctki2_bbox[5] : 1)&& \
+ (cctki2_ldir==-1 ? cctki2_bbox[6] : 1) && (cctki2_ldir==+1 ? cctki2_bbox[7] : 1); \
+ if (cctki2_all_bbox && cctki2_any_bbox) { \
+ int const cctki2_bmin[] = { \
+ cctki2_idir==-1 ? 0 : cctki2_idir==0 ? cctki2_blo[0] : cctki2_lssh[0] - cctki2_bhi[0], \
+ cctki2_jdir==-1 ? 0 : cctki2_jdir==0 ? cctki2_blo[1] : cctki2_lssh[1] - cctki2_bhi[1], \
+ cctki2_kdir==-1 ? 0 : cctki2_kdir==0 ? cctki2_blo[2] : cctki2_lssh[2] - cctki2_bhi[2], \
+ cctki2_ldir==-1 ? 0 : cctki2_ldir==0 ? cctki2_blo[3] : cctki2_lssh[3] - cctki2_bhi[3], \
+ }; \
+ int const cctki2_bmax[] = { \
+ cctki2_idir==-1 ? cctki2_blo[0] : cctki2_idir==0 ? cctki2_lssh[0] - cctki2_bhi[0] : cctki2_lssh[0], \
+ cctki2_jdir==-1 ? cctki2_blo[1] : cctki2_jdir==0 ? cctki2_lssh[1] - cctki2_bhi[1] : cctki2_lssh[1], \
+ cctki2_kdir==-1 ? cctki2_blo[2] : cctki2_kdir==0 ? cctki2_lssh[2] - cctki2_bhi[2] : cctki2_lssh[2], \
+ cctki2_ldir==-1 ? cctki2_blo[3] : cctki2_ldir==0 ? cctki2_lssh[3] - cctki2_bhi[3] : cctki2_lssh[3], \
+ }; \
+ CCTK_LOOP4STR_NORMAL(name##_intboundaries, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ cctki2_idir,cctki2_jdir,cctki2_kdir,cctki2_ldir, \
+ cctki2_bmin[0],cctki2_bmin[1],cctki2_bmin[2],cctki2_bmin[3], \
+ cctki2_bmax[0],cctki2_bmax[1],cctki2_bmax[2],cctki2_bmax[3], \
+ cctki2_cctkGH->cctk_lsh[0], \
+ cctki2_cctkGH->cctk_lsh[1], \
+ cctki2_cctkGH->cctk_lsh[2], \
+ cctki2_cctkGH->cctk_lsh[3], \
+ cctki2_istr1) { \
+
+#define CCTK_ENDLOOP4STR_INTBOUNDARIES(name) \
+ } CCTK_ENDLOOP4STR_NORMAL(name##_intboundaries); \
+ } /* if bbox */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ } /* for dir */ \
+ typedef cctki2_loop4_intboundaries_##name cctki2_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_ALL */
+
+#define CCTK_LOOP4_ALL(name, cctkGH, \
+ i,j,k,l) \
+ CCTK_LOOP4STR_ALL(name, (cctkGH), \
+ i,j,k,l, \
+ 1) \
+
+#define CCTK_ENDLOOP4_ALL(name) \
+ CCTK_ENDLOOP4STR_ALL(name) \
+
+#define CCTK_LOOP4STR_ALL(name, cctkGH, \
+ i,j,k,l, \
+ istr) \
+ do { \
+ typedef int cctki3_loop4_all_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 4) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP4_ALL can only be used in 4 dimensions"); \
+ } \
+ CCTK_LOOP4STR(name##_all, \
+ i,j,k,l, \
+ 0,0,0,0, \
+ cctki3_cctkGH->CCTK_LSSH(0,0), \
+ cctki3_cctkGH->CCTK_LSSH(0,1), \
+ cctki3_cctkGH->CCTK_LSSH(0,2), \
+ cctki3_cctkGH->CCTK_LSSH(0,3), \
+ cctki3_cctkGH->cctk_lsh[0], \
+ cctki3_cctkGH->cctk_lsh[1], \
+ cctki3_cctkGH->cctk_lsh[2], \
+ cctki3_cctkGH->cctk_lsh[3], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP4STR_ALL(name) \
+ } CCTK_ENDLOOP4STR(name##_all); \
+ typedef cctki3_loop4_all_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INT */
+
+#define CCTK_LOOP4_INT(name, cctkGH, \
+ i,j,k,l) \
+ CCTK_LOOP4STR_INT(name, (cctkGH), \
+ i,j,k,l, \
+ 1) \
+
+#define CCTK_ENDLOOP4_INT(name) \
+ CCTK_ENDLOOP4STR_INT(name) \
+
+#define CCTK_LOOP4STR_INT(name, cctkGH, \
+ i,j,k,l, \
+ istr) \
+ do { \
+ typedef int cctki3_loop4_int_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 4) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP4_INT can only be used in 4 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [8]; \
+ CCTK_INT cctki3_is_ghostbnd[8]; \
+ CCTK_INT cctki3_is_symbnd [8]; \
+ CCTK_INT cctki3_is_physbnd [8]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 8, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP4STR_INTERIOR(name##_int, \
+ cctki3_cctkGH, \
+ i,j,k,l, \
+ cctki3_bndsize[0],cctki3_bndsize[2],cctki3_bndsize[4],cctki3_bndsize[6], \
+ cctki3_bndsize[1],cctki3_bndsize[3],cctki3_bndsize[5],cctki3_bndsize[7], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP4STR_INT(name) \
+ } CCTK_ENDLOOP4STR_INTERIOR(name##_int); \
+ typedef cctki3_loop4_int_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_BND */
+
+#define CCTK_LOOP4_BND(name, cctkGH, \
+ i,j,k,l, \
+ ni,nj,nk,nl) \
+ CCTK_LOOP4STR_BND(name, (cctkGH), \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ 1) \
+
+#define CCTK_ENDLOOP4_BND(name) \
+ CCTK_ENDLOOP4STR_BND(name) \
+
+#define CCTK_LOOP4STR_BND(name, cctkGH, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ istr) \
+ do { \
+ typedef int cctki3_loop4_bnd_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 4) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP4_BND can only be used in 4 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [8]; \
+ CCTK_INT cctki3_is_ghostbnd[8]; \
+ CCTK_INT cctki3_is_symbnd [8]; \
+ CCTK_INT cctki3_is_physbnd [8]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize, cctki3_is_physbnd)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 8, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP4STR_BOUNDARIES(name##_bnd, \
+ cctki3_cctkGH, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ cctki3_bndsize[0],cctki3_bndsize[2],cctki3_bndsize[4],cctki3_bndsize[6], \
+ cctki3_bndsize[1],cctki3_bndsize[3],cctki3_bndsize[5],cctki3_bndsize[7], \
+ cctki3_is_physbnd[0],cctki3_is_physbnd[2],cctki3_is_physbnd[4],cctki3_is_physbnd[6], \
+ cctki3_is_physbnd[1],cctki3_is_physbnd[3],cctki3_is_physbnd[5],cctki3_is_physbnd[7], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP4STR_BND(name) \
+ } CCTK_ENDLOOP4STR_BOUNDARIES(name##_bnd); \
+ typedef cctki3_loop4_bnd_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+
+
+/* LOOP_INTBND */
+
+#define CCTK_LOOP4_INTBND(name, cctkGH, \
+ i,j,k,l, \
+ ni,nj,nk,nl) \
+ CCTK_LOOP4STR_INTBND(name, (cctkGH), \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ 1) \
+
+#define CCTK_ENDLOOP4_INTBND(name) \
+ CCTK_ENDLOOP4STR_INTBND(name) \
+
+#define CCTK_LOOP4STR_INTBND(name, cctkGH, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ istr) \
+ do { \
+ typedef int cctki3_loop4_intbnd_##name; \
+ cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH); \
+ if (cctki3_cctkGH->cctk_dim != 4) { \
+ _Pragma("omp critical") \
+ CCTK_WARN(CCTK_WARN_ABORT, \
+ "The macro CCTK_LOOP4_INTBND can only be used in 4 dimensions"); \
+ } \
+ CCTK_INT cctki3_bndsize [8]; \
+ CCTK_INT cctki3_is_ghostbnd[8]; \
+ CCTK_INT cctki3_is_symbnd [8]; \
+ CCTK_INT cctki3_is_physbnd [8]; \
+ _Pragma("omp single copyprivate(cctki3_bndsize, cctki3_is_physbnd)") \
+ GetBoundarySizesAndTypes \
+ (cctki3_cctkGH, 8, cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd); \
+ CCTK_LOOP4STR_INTBOUNDARIES(name##_intbnd, \
+ cctki3_cctkGH, \
+ i,j,k,l, \
+ ni,nj,nk,nl, \
+ cctki3_bndsize[0],cctki3_bndsize[2],cctki3_bndsize[4],cctki3_bndsize[6], \
+ cctki3_bndsize[1],cctki3_bndsize[3],cctki3_bndsize[5],cctki3_bndsize[7], \
+ cctki3_is_physbnd[0],cctki3_is_physbnd[2],cctki3_is_physbnd[4],cctki3_is_physbnd[6], \
+ cctki3_is_physbnd[1],cctki3_is_physbnd[3],cctki3_is_physbnd[5],cctki3_is_physbnd[7], \
+ (istr)) { \
+
+#define CCTK_ENDLOOP4STR_INTBND(name) \
+ } CCTK_ENDLOOP4STR_INTBOUNDARIES(name##_intbnd); \
+ typedef cctki3_loop4_intbnd_##name cctki3_ensure_proper_nesting; \
+ } while (0) \
+
+#endif /* #ifdef CCODE */
+
+
+
+#ifdef FCODE
+
+/* LOOP */
+
+#define CCTK_LOOP4_DECLARE(name) \
+ && integer :: name/**/_imin,name/**/_jmin,name/**/_kmin,name/**/_lmin \
+ && integer :: name/**/_imax,name/**/_jmax,name/**/_kmax,name/**/_lmax \
+ && integer :: name/**/_istr \
+
+#define CCTK_LOOP4_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP4(name, \
+ i,j,k,l, \
+ imin,jmin,kmin,lmin, \
+ imax,jmax,kmax,lmax, \
+ ilsh,jlsh,klsh,llsh) \
+ CCTK_LOOP4STR(name, \
+ i,j,k,l, \
+ imin,jmin,kmin,lmin, \
+ imax,jmax,kmax,lmax, \
+ ilsh,jlsh,klsh,llsh, \
+ 1) \
+
+#define CCTK_LOOP4STR(name, \
+ i,j,k,l, \
+ imin,jmin,kmin,lmin, \
+ imax,jmax,kmax,lmax, \
+ ilsh,jlsh,klsh,llsh, \
+ istr) \
+ && name/**/_imin = imin \
+ && name/**/_jmin = jmin \
+ && name/**/_kmin = kmin \
+ && name/**/_lmin = lmin \
+ && name/**/_imax = imax \
+ && name/**/_jmax = jmax \
+ && name/**/_kmax = kmax \
+ && name/**/_lmax = lmax \
+ && name/**/_istr = istr \
+ && do l = name/**/_lmin, name/**/_lmax \
+ && do k = name/**/_kmin, name/**/_kmax \
+ && do j = name/**/_jmin, name/**/_jmax \
+ && do i = name/**/_imin, name/**/_imax \
+
+#define CCTK_ENDLOOP4(name) \
+ CCTK_ENDLOOP4STR(name) \
+
+#define CCTK_ENDLOOP4STR(name) \
+ && end do \
+ && end do \
+ && end do \
+ && end do \
+
+
+
+/* LOOP_ALL */
+
+#define CCTK_LOOP4_ALL_DECLARE(name) \
+ CCTK_LOOP4_DECLARE(name) \
+
+#define CCTK_LOOP4_ALL_OMP_PRIVATE(name) \
+ CCTK_LOOP4_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP4_ALL(name, \
+ i,j,k,l) \
+ CCTK_LOOP4STR_ALL(name, \
+ i,j,k,l, \
+ 1) \
+
+#define CCTK_LOOP4STR_ALL(name, \
+ i,j,k,l, \
+ istr) \
+ CCTK_LOOP4STR(name, \
+ i,j,k,l, \
+ 1,1,1,1, \
+ CCTK_LSSH(0,1),CCTK_LSSH(0,2),CCTK_LSSH(0,3),CCTK_LSSH(0,4), \
+ cctk_lsh(1),cctk_lsh(2),cctk_lsh(3),cctk_lsh(4), \
+ istr) \
+
+#define CCTK_ENDLOOP4_ALL(name) \
+ CCTK_ENDLOOP4STR_ALL(name) \
+
+#define CCTK_ENDLOOP4STR_ALL(name) \
+ CCTK_ENDLOOP4(name) \
+
+
+
+/* LOOP_INTERIOR */
+
+#define CCTK_LOOP4_INTERIOR_DECLARE(name) \
+ CCTK_LOOP4_DECLARE(name) \
+
+#define CCTK_LOOP4_INTERIOR_OMP_PRIVATE(name) \
+ CCTK_LOOP4_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP4_INTERIOR(name, \
+ i,j,k,l, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi) \
+ CCTK_LOOP4STR_INTERIOR(name, \
+ i,j,k,l, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi, \
+ 1) \
+
+#define CCTK_LOOP4STR_INTERIOR(name, \
+ i,j,k,l, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi, \
+ istr) \
+ CCTK_LOOP4STR(name, \
+ i,j,k,l, \
+ (iblo),(jblo),(kblo),(lblo), \
+ CCTK_LSSH(0,1)-(ibhi), \
+ CCTK_LSSH(0,2)-(jbhi), \
+ CCTK_LSSH(0,3)-(kbhi), \
+ CCTK_LSSH(0,4)-(lbhi), \
+ cctk_lsh(1),cctk_lsh(2),cctk_lsh(3),cctk_lsh(4), \
+ istr) \
+
+#define CCTK_ENDLOOP4_INTERIOR(name) \
+ CCTK_ENDLOOP4STR_INTERIOR(name) \
+
+#define CCTK_ENDLOOP4STR_INTERIOR(name) \
+ CCTK_ENDLOOP4(name) \
+
+
+
+/* LOOP_BOUNDARIES */
+
+#define CCTK_LOOP4_BOUNDARIES_DECLARE(name) \
+ CCTK_LOOP4_DECLARE(name) \
+ && integer :: lc_bmin(4), lc_bmax(4) \
+ && integer :: lc_blo(4), lc_bhi(4) \
+ && integer :: lc_istr \
+ && integer :: lc_dir, lc_face \
+ && integer :: lc_d \
+
+#define CCTK_LOOP4_BOUNDARIES_OMP_PRIVATE(name) \
+ CCTK_LOOP4_OMP_PRIVATE(name) \
+
+#define CCTK_LOOP4_BOUNDARIES(name, \
+ i,j,k,l, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi) \
+ CCTK_LOOP4STR_BOUNDARIES(name, \
+ i,j,k,l, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi, \
+ 1) \
+
+#define CCTK_LOOP4STR_BOUNDARIES(name, \
+ i,j,k,l, \
+ iblo,jblo,kblo,lblo, \
+ ibhi,jbhi,kbhi,lbhi, \
+ istr) \
+ && lc_blo = (/ iblo,jblo,kblo,lblo /) \
+ && lc_bhi = (/ ibhi,jbhi,kbhi,lbhi /) \
+ && lc_istr = istr \
+ && do lc_dir=1,4 \
+ && do lc_face=1,2 \
+ && do lc_d=1,4 \
+ && lc_bmin(lc_d) = 1 \
+ && lc_bmax(lc_d) = CCTK_LSSH(0,lc_d) \
+ && if (lc_d<lc_dir) then \
+ && lc_bmin(lc_d) = lc_bmin(lc_d)+lc_blo(lc_d) \
+ && lc_bmax(lc_d) = lc_bmax(lc_d)-lc_bhi(lc_d) \
+ && end if \
+ && end do \
+ && if (lc_face==1) then \
+ && lc_bmax(lc_dir) = lc_bmin(lc_dir)+lc_blo(lc_dir) \
+ && else \
+ && lc_bmin(lc_dir) = lc_bmax(lc_dir)-lc_bhi(lc_dir) \
+ && end if \
+ CCTK_LOOP4STR(name, \
+ i,j,k,l, \
+ lc_bmin(1),lc_bmin(2),lc_bmin(3),lc_bmin(4), \
+ lc_bmax(1),lc_bmax(2),lc_bmax(3),lc_bmax(4), \
+ cctk_lsh(1),cctk_lsh(2),cctk_lsh(3),cctk_lsh(4), \
+ lc_istr) \
+
+#define CCTK_ENDLOOP4_BOUNDARIES(name) \
+ CCTK_ENDLOOP4STR_BOUNDARIES(name) \
+
+#define CCTK_ENDLOOP4STR_BOUNDARIES(name) \
+ CCTK_ENDLOOP4(name) \
+ && end do /* face */ \
+ && end do /* dir */ \
+
+#endif /* #ifdef FCODE */
+
+
#endif /* #ifndef _CCTK_LOOP_H_ */
diff --git a/src/include/cctk_Loop.h.pl b/src/include/cctk_Loop.h.pl
new file mode 100755
index 00000000..3a03272f
--- /dev/null
+++ b/src/include/cctk_Loop.h.pl
@@ -0,0 +1,840 @@
+#! /usr/bin/perl -w
+
+# This perl script generates the include file "cctk_Loop.h".
+
+
+
+# API:
+
+# There is a basic looping macro (LOOP) which takes the array size and
+# loop bounds as arguments. This macro can loop over all arrays, both
+# grid functions and grid arrays. A second version of this macro
+# (LOOP_NORMAL) also provides information about the normal to the
+# boundary and distance to the boundary to the loop kernel.
+
+# There are three specialised versions that take instead cctkGH and
+# the boundary sizes as arguments (LOOP_INTERIOR, LOOP_BOUNDARIES, and
+# LOOP_INTBOUNDARIES). These macros are intended for grid functions
+# only, and loop over the respective subsets of points, either only
+# interior points, or all physical boundaries, or the "interior"
+# physical boundaries (excluding edges and corners that are also
+# ghosts or symmetry points).
+
+# Note: Edges and corners can have several boundary types at once,
+# e.g. can be both a physical and a symmetry point. LOOP_BOUNDARY and
+# LOOP_INTBOUNDARY treats these different: LOOP_BOUNDARY loops over
+# all points that are physical boundaries (independent of whether they
+# also are symmetry or ghost boundaries), while LOOP_INTBOUNARY loops
+# over those points that are only physical boundaries (and excludes
+# any points that belongs to a symmetry or ghost boundary).
+# LOOP_BOUNDARY does not require applying a symmetry condition or
+# synchronisation afterwards (but does not allow taking tangential
+# derivatives); LOOP_INTBOUNDARY allows taking tangential derivatives
+# (but requires applying symmetry boundaries and synchronising
+# afterwards).
+
+# There are four specialised versions that take instead a cctkGH
+# (LOOP_ALL, LOOP_INT, LOOP_BND, and LOOP_INTBND). These macros are
+# intended for grid functions only and obtain the boundary sizes from
+# CoordBase via an aliased function. They loop over the respective
+# subsets of points, either all points, or all interior points, or all
+# physical boundaries, or the "interior" physical boundaries (see
+# above).
+
+# Each macro exists in two versions, a regular and a strided one
+# (STR). The strided macros are intended for vectorised code, and the
+# stride should be the vector size.
+
+# Each macro exists for variable numbers of dimensions, currently 1
+# through 4.
+
+
+
+# Internals:
+
+# Since these macros call each other, it is important that the local
+# variables they declare do not conflict. Therefore, we denote four
+# "levels" of macros, corresponding to the description above:
+# level 0: LOOP_NORMAL
+# level 1: LOOP
+# level 2: LOOP_INTERIOR, LOOP_BOUNDARIES, LOOP_INTBOUNDARIES
+# level 3: LOOP_ALL, LOOP_INT, LOOP_BND, LOOP_INTBND
+# Each level may only call macros of a lower level. All local
+# variables carry a prefix "cctki[LEVEL]_" to ensure that there are no
+# naming conflicts.
+
+
+
+use strict;
+
+
+
+# Global variable: number of dimensions (1 to 4)
+our $dim;
+
+
+
+# Expand [DIM] to the (global) number of dimensions
+sub expand ($)
+{
+ my ($str) = @_;
+ my $dim2 = 2*$dim;
+ $str =~ s{\[DIM\]}{$dim}g;
+ $str =~ s{\[2\*DIM\]}{$dim2}g;
+ return $str;
+}
+
+# Add a newline
+sub nl ($)
+{
+ my ($str) = @_;
+ return "$str\n";
+}
+
+# Add a backslash and newline
+sub bsnl ($)
+{
+ my ($str) = @_;
+ return "$str \\\n";
+}
+
+# Repeat a string once for each dimension, expanding 'I' and 'C' to a
+# different number (0,1,2,3) and character (i,j,k,l) each time
+sub rpt ($)
+{
+ my ($str) = @_;
+ my @ret;
+ for my $d (1..$dim) {
+ my $int = $d-1;
+ my $int1 = $int+1;
+ my $int2 = 2*$int;
+ my $int21 = 2*$int+1;
+ my $char = ('i','j','k','l')[$d-1];
+ my $tmp = $str;
+ $tmp =~ s{\[I\]}{$int}g;
+ $tmp =~ s{\[I\+1\]}{$int1}g;
+ $tmp =~ s{\[2\*I\]}{$int2}g;
+ $tmp =~ s{\[2\*I\+1\]}{$int21}g;
+ $tmp =~ s{\[C\]}{$char}g;
+ push @ret, $tmp;
+ }
+ return @ret;
+}
+
+# Terminate a list (intersperse a string, and add the string at the
+# end as well)
+sub term ($@)
+{
+ my ($str, @txt) = @_;
+ return (join $str, @txt) . $str;
+}
+
+# Separate a list (intersperse a string, but not at the end)
+sub sep ($@)
+{
+ my ($str, @txt) = @_;
+ return (join $str, @txt);
+}
+
+# Repeat and separate with a comma
+sub crpt ($)
+{
+ my ($str) = @_;
+ return (sep ',', rpt $str);
+}
+
+# The first argument is a list reference to force a list context for
+# wherever this argument is evaluated
+sub bsnlsep ($;$$)
+{
+ my ($txt, $str1, $str2) = @_;
+ $str1 = '' if ! defined $str1;
+ $str2 = $str1 if ! defined $str2;
+ my @ret;
+ for my $t (@$txt[0..$#$txt-1]) {
+ push @ret, "$t$str1";
+ }
+ if ($#$txt >= 0) {
+ push @ret, "$$txt[$#$txt]$str2";
+ }
+ return map {bsnl $_} @ret;
+}
+
+
+
+my @lines;
+
+# Header
+push @lines, (
+ (nl '#ifndef _CCTK_LOOP_H_'),
+ (nl '#define _CCTK_LOOP_H_'),
+ (nl ''),
+ (nl '/* WARNING: This file is auto-generated. Do not edit. */'),
+ (nl '/* Edit cctk_Loop.h.pl instead, and then re-generate this file via */'),
+ (nl '/* perl cctk_Loop.h.pl.pl */'),
+ (nl '/* Documentation can also be found in "cctk_Loop.h.pl". */'),
+ (nl ''),
+ (nl '#ifdef CCODE'),
+ (nl '# include <cctk_Config.h>'),
+ (nl '# include <cctk_WarnLevel.h>'),
+ (nl '# include <cGH.h>'),
+ (nl '# include <assert.h>'),
+ (nl '#endif /* #ifdef CCODE */'),
+ );
+
+
+
+for $dim (1,2,3,4) {
+
+ push @lines, map {expand $_} (
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* [DIM]D */'),
+ (nl ''),
+ (nl '#ifdef CCODE'),
+ (nl ''),
+ (nl '/* LOOP */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_NORMAL(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt '[C]dir').','),
+ (bsnl ' '.(crpt '[C]min').','),
+ (bsnl ' '.(crpt '[C]max').','),
+ (bsnl ' '.(crpt '[C]lsh').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_NORMAL(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt '([C]dir)').','),
+ (bsnl ' '.(crpt '([C]min)').','),
+ (bsnl ' '.(crpt '([C]max)').','),
+ (bsnl ' '.(crpt '([C]lsh)').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_NORMAL(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_NORMAL(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_NORMAL(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt '[C]dir').','),
+ (bsnl ' '.(crpt '[C]min').','),
+ (bsnl ' '.(crpt '[C]max').','),
+ (bsnl ' '.(crpt '[C]lsh').','),
+ (bsnl ' istr)'),
+ (bsnl ' do {'),
+ (bsnl ' typedef int cctki0_loop[DIM]_normal_##name;'),
+ (rpt (bsnl ' int const cctki0_[C]dir = ([C]dir);')),
+ (rpt (bsnl ' int const cctki0_[C]min = ([C]min);')),
+ (rpt (bsnl ' int const cctki0_[C]max = ([C]max);')),
+ (bsnl ' int const cctki0_istr CCTK_ATTRIBUTE_UNUSED = (istr);'),
+ (bsnl ' assert(cctki0_istr == 1);'),
+ (bsnl ' _Pragma("omp for")'), # collapse([DIM])
+ (reverse (rpt (bsnl ' for (int [C]=cctki0_[C]min; [C]<cctki0_[C]max; ++[C]) {'))),
+ (rpt (bsnl ' int const n[C] CCTK_ATTRIBUTE_UNUSED = cctki0_[C]dir<0 ? [C]+1 : cctki0_[C]dir==0 ? 0 : cctki0_[C]max-[C];')),
+ (bsnl ' {'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_NORMAL(name)'),
+ (bsnl ' }'),
+ (rpt (bsnl ' }')),
+ (bsnl ' typedef cctki0_loop[DIM]_normal_##name cctki0_ensure_proper_nesting;'),
+ (bsnl ' } while (0)'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM](name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]min').','),
+ (bsnl ' '.(crpt '[C]max').','),
+ (bsnl ' '.(crpt '[C]lsh').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '([C]min)').','),
+ (bsnl ' '.(crpt '([C]max)').','),
+ (bsnl ' '.(crpt '([C]lsh)').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM](name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]min').','),
+ (bsnl ' '.(crpt '[C]max').','),
+ (bsnl ' '.(crpt '[C]lsh').','),
+ (bsnl ' istr)'),
+ (bsnl ' CCTK_LOOP[DIM]STR_NORMAL(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'cctki1_n[C]').','),
+ (bsnl ' '.(crpt '0').','),
+ (bsnl ' '.(crpt '[C]min').','),
+ (bsnl ' '.(crpt '[C]max').','),
+ (bsnl ' '.(crpt '[C]lsh').','),
+ (bsnl ' istr)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_NORMAL(name)'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* LOOP_INTERIOR */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_INTERIOR(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_INTERIOR(name, (cctkGH),'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '([C]blo)').','),
+ (bsnl ' '.(crpt '([C]bhi)').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_INTERIOR(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_INTERIOR(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_INTERIOR(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').','),
+ (bsnl ' istr)'),
+ (bsnl ' do {'),
+ (bsnl ' typedef int cctki2_loop[DIM]_interior_##name;'),
+ (bsnl ' cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH);'),
+ (bsnl ' if (cctki2_cctkGH->cctk_dim != [DIM]) {'),
+ (bsnl ' _Pragma("omp critical")'),
+ (bsnl ' CCTK_WARN(CCTK_WARN_ABORT,'),
+ (bsnl ' "The macro CCTK_LOOP[DIM]_INTERIOR can only be used in [DIM] dimensions");'),
+ (bsnl ' }'),
+ (bsnl ' CCTK_LOOP[DIM]STR(name##_interior,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '([C]blo)').','),
+ (rpt (bsnl ' cctki2_cctkGH->CCTK_LSSH(0,[I])-([C]bhi),')),
+ (rpt (bsnl ' cctki2_cctkGH->cctk_lsh[[I]],')),
+ (bsnl ' (istr)) {'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_INTERIOR(name)'),
+ (bsnl ' } CCTK_ENDLOOP[DIM]STR(name##_interior);'),
+ (bsnl ' typedef cctki2_loop[DIM]_interior_##name cctki2_ensure_proper_nesting;'),
+ (bsnl ' } while(0)'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* LOOP_BOUNDARIES */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_BOUNDARIES(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').','),
+ (bsnl ' '.(crpt '[C]bboxlo').','),
+ (bsnl ' '.(crpt '[C]bboxhi').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_BOUNDARIES(name, (cctkGH),'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt '([C]blo)').','),
+ (bsnl ' '.(crpt '([C]bhi)').','),
+ (bsnl ' '.(crpt '([C]bboxlo)').','),
+ (bsnl ' '.(crpt '([C]bboxhi)').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_BOUNDARIES(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_BOUNDARIES(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_BOUNDARIES(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').','),
+ (bsnl ' '.(crpt '[C]bboxlo').','),
+ (bsnl ' '.(crpt '[C]bboxhi').','),
+ (bsnl ' istr)'),
+ (bsnl ' do {'),
+ (bsnl ' typedef int cctki2_loop[DIM]_boundaries_##name;'),
+ (bsnl ' cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH);'),
+ (bsnl ' if (cctki2_cctkGH->cctk_dim != [DIM]) {'),
+ (bsnl ' _Pragma("omp critical")'),
+ (bsnl ' CCTK_WARN(CCTK_WARN_ABORT,'),
+ (bsnl ' "The macro CCTK_LOOP[DIM]_BOUNDARIES can only be used in [DIM] dimensions");'),
+ (bsnl ' }'),
+ (bsnl ' int const cctki2_blo[] = { '.(crpt '([C]blo)').' };'),
+ (bsnl ' int const cctki2_bhi[] = { '.(crpt '([C]bhi)').' };'),
+ (bsnl ' int const cctki2_bbox[] = { '.(crpt '([C]bboxlo), ([C]bboxhi)').' };'),
+ (bsnl ' int const cctki2_lssh[] = { '.(crpt 'cctki2_cctkGH->CCTK_LSSH(0,[I])').' };'),
+ (bsnl ' int const cctki2_istr1 CCTK_ATTRIBUTE_UNUSED = (istr);'),
+ (bsnl ' /* Loop over all faces, edges, and corners */'),
+ (reverse (rpt (bsnl ' for (int cctki2_[C]dir=-1; cctki2_[C]dir<=+1; ++cctki2_[C]dir) {'))),
+ (bsnl ' int cctki2_any_bbox ='),
+ (bsnlsep [rpt ' (cctki2_[C]dir==-1 ? cctki2_bbox[[2*I]] : 0) || (cctki2_[C]dir==+1 ? cctki2_bbox[[2*I+1]] : 0)'], '||', ';'),
+ (bsnl ' if (cctki2_any_bbox) {'),
+ (bsnl ' int const cctki2_bmin[] = {'),
+ (rpt (bsnl ' cctki2_[C]dir==-1 ? 0 : cctki2_[C]dir==0 ? cctki2_blo[[I]] : cctki2_lssh[[I]] - cctki2_bhi[[I]],')),
+ (bsnl ' };'),
+ (bsnl ' int const cctki2_bmax[] = {'),
+ (rpt (bsnl ' cctki2_[C]dir==-1 ? cctki2_blo[[I]] : cctki2_[C]dir==0 ? cctki2_lssh[[I]] - cctki2_bhi[[I]] : cctki2_lssh[[I]],')),
+ (bsnl ' };'),
+ (bsnl ' CCTK_LOOP[DIM]STR_NORMAL(name##_boundaries,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt 'cctki2_[C]dir').','),
+ (bsnl ' '.(crpt 'cctki2_bmin[[I]]').','),
+ (bsnl ' '.(crpt 'cctki2_bmax[[I]]').','),
+ (rpt (bsnl ' cctki2_cctkGH->cctk_lsh[[I]],')),
+ (bsnl ' cctki2_istr1) {'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_BOUNDARIES(name)'),
+ (bsnl ' } CCTK_ENDLOOP[DIM]STR_NORMAL(name##_boundaries);'),
+ (bsnl ' } /* if bbox */'),
+ (reverse (rpt (bsnl ' } /* for dir */'))),
+ (bsnl ' typedef cctki2_loop[DIM]_boundaries_##name cctki2_ensure_proper_nesting;'),
+ (bsnl ' } while (0)'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* LOOP_INTBOUNDARIES */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_INTBOUNDARIES(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').','),
+ (bsnl ' '.(crpt '[C]bboxlo').','),
+ (bsnl ' '.(crpt '[C]bboxhi').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_INTBOUNDARIES(name, (cctkGH),'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt '([C]blo)').','),
+ (bsnl ' '.(crpt '([C]bhi)').','),
+ (bsnl ' '.(crpt '([C]bboxlo)').','),
+ (bsnl ' '.(crpt '([C]bboxhi)').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_INTBOUNDARIES(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_INTBOUNDARIES(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_INTBOUNDARIES(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').','),
+ (bsnl ' '.(crpt '[C]bboxlo').','),
+ (bsnl ' '.(crpt '[C]bboxhi').','),
+ (bsnl ' istr)'),
+ (bsnl ' do {'),
+ (bsnl ' typedef int cctki2_loop[DIM]_intboundaries_##name;'),
+ (bsnl ' cGH const *CCTK_RESTRICT const cctki2_cctkGH = (cctkGH);'),
+ (bsnl ' if (cctki2_cctkGH->cctk_dim != [DIM]) {'),
+ (bsnl ' _Pragma("omp critical")'),
+ (bsnl ' CCTK_WARN(CCTK_WARN_ABORT,'),
+ (bsnl ' "The macro CCTK_LOOP[DIM]_INTBOUNDARIES can only be used in [DIM] dimensions");'),
+ (bsnl ' }'),
+ (bsnl ' int const cctki2_blo[] = { '.(crpt '([C]blo)').' };'),
+ (bsnl ' int const cctki2_bhi[] = { '.(crpt '([C]bhi)').' };'),
+ (bsnl ' int const cctki2_bbox[] = { '.(crpt '([C]bboxlo), ([C]bboxhi)').' };'),
+ (bsnl ' int const cctki2_lssh[] = { '.(crpt 'cctki2_cctkGH->CCTK_LSSH(0,[I])').' };'),
+ (bsnl ' int const cctki2_istr1 CCTK_ATTRIBUTE_UNUSED = (istr);'),
+ (bsnl ' /* Loop over all faces, edges, and corners */'),
+ (reverse (rpt (bsnl ' for (int cctki2_[C]dir=-1; cctki2_[C]dir<=+1; ++cctki2_[C]dir) {'))),
+ (bsnl ' int cctki2_any_bbox ='),
+ (bsnlsep [rpt ' (cctki2_[C]dir==-1 ? cctki2_bbox[[2*I]] : 0) || (cctki2_[C]dir==+1 ? cctki2_bbox[[2*I+1]] : 0)'], '||', ';'),
+ (bsnl ' int cctki2_all_bbox ='),
+ (bsnlsep [rpt ' (cctki2_[C]dir==-1 ? cctki2_bbox[[2*I]] : 1) && (cctki2_[C]dir==+1 ? cctki2_bbox[[2*I+1]] : 1)'], '&&', ';'),
+ (bsnl ' if (cctki2_all_bbox && cctki2_any_bbox) {'),
+ (bsnl ' int const cctki2_bmin[] = {'),
+ (rpt (bsnl ' cctki2_[C]dir==-1 ? 0 : cctki2_[C]dir==0 ? cctki2_blo[[I]] : cctki2_lssh[[I]] - cctki2_bhi[[I]],')),
+ (bsnl ' };'),
+ (bsnl ' int const cctki2_bmax[] = {'),
+ (rpt (bsnl ' cctki2_[C]dir==-1 ? cctki2_blo[[I]] : cctki2_[C]dir==0 ? cctki2_lssh[[I]] - cctki2_bhi[[I]] : cctki2_lssh[[I]],')),
+ (bsnl ' };'),
+ (bsnl ' CCTK_LOOP[DIM]STR_NORMAL(name##_intboundaries,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt 'cctki2_[C]dir').','),
+ (bsnl ' '.(crpt 'cctki2_bmin[[I]]').','),
+ (bsnl ' '.(crpt 'cctki2_bmax[[I]]').','),
+ (rpt (bsnl ' cctki2_cctkGH->cctk_lsh[[I]],')),
+ (bsnl ' cctki2_istr1) {'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_INTBOUNDARIES(name)'),
+ (bsnl ' } CCTK_ENDLOOP[DIM]STR_NORMAL(name##_intboundaries);'),
+ (bsnl ' } /* if bbox */'),
+ (reverse (rpt (bsnl ' } /* for dir */'))),
+ (bsnl ' typedef cctki2_loop[DIM]_intboundaries_##name cctki2_ensure_proper_nesting;'),
+ (bsnl ' } while (0)'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* LOOP_ALL */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_ALL(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_ALL(name, (cctkGH),'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_ALL(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_ALL(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_ALL(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' istr)'),
+ (bsnl ' do {'),
+ (bsnl ' typedef int cctki3_loop[DIM]_all_##name;'),
+ (bsnl ' cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH);'),
+ (bsnl ' if (cctki3_cctkGH->cctk_dim != [DIM]) {'),
+ (bsnl ' _Pragma("omp critical")'),
+ (bsnl ' CCTK_WARN(CCTK_WARN_ABORT,'),
+ (bsnl ' "The macro CCTK_LOOP[DIM]_ALL can only be used in [DIM] dimensions");'),
+ (bsnl ' }'),
+ (bsnl ' CCTK_LOOP[DIM]STR(name##_all,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '0').','),
+ (rpt (bsnl ' cctki3_cctkGH->CCTK_LSSH(0,[I]),')),
+ (rpt (bsnl ' cctki3_cctkGH->cctk_lsh[[I]],')),
+ (bsnl ' (istr)) {'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_ALL(name)'),
+ (bsnl ' } CCTK_ENDLOOP[DIM]STR(name##_all);'),
+ (bsnl ' typedef cctki3_loop[DIM]_all_##name cctki3_ensure_proper_nesting;'),
+ (bsnl ' } while (0)'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* LOOP_INT */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_INT(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_INT(name, (cctkGH),'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_INT(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_INT(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_INT(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' istr)'),
+ (bsnl ' do {'),
+ (bsnl ' typedef int cctki3_loop[DIM]_int_##name;'),
+ (bsnl ' cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH);'),
+ (bsnl ' if (cctki3_cctkGH->cctk_dim != [DIM]) {'),
+ (bsnl ' _Pragma("omp critical")'),
+ (bsnl ' CCTK_WARN(CCTK_WARN_ABORT,'),
+ (bsnl ' "The macro CCTK_LOOP[DIM]_INT can only be used in [DIM] dimensions");'),
+ (bsnl ' }'),
+ (bsnl ' CCTK_INT cctki3_bndsize [[2*DIM]];'),
+ (bsnl ' CCTK_INT cctki3_is_ghostbnd[[2*DIM]];'),
+ (bsnl ' CCTK_INT cctki3_is_symbnd [[2*DIM]];'),
+ (bsnl ' CCTK_INT cctki3_is_physbnd [[2*DIM]];'),
+ (bsnl ' _Pragma("omp single copyprivate(cctki3_bndsize)")'),
+ (bsnl ' GetBoundarySizesAndTypes'),
+ (bsnl ' (cctki3_cctkGH, [2*DIM], cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd);'),
+ (bsnl ' CCTK_LOOP[DIM]STR_INTERIOR(name##_int,'),
+ (bsnl ' cctki3_cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'cctki3_bndsize[[2*I]]').','),
+ (bsnl ' '.(crpt 'cctki3_bndsize[[2*I+1]]').','),
+ (bsnl ' (istr)) {'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_INT(name)'),
+ (bsnl ' } CCTK_ENDLOOP[DIM]STR_INTERIOR(name##_int);'),
+ (bsnl ' typedef cctki3_loop[DIM]_int_##name cctki3_ensure_proper_nesting;'),
+ (bsnl ' } while (0)'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* LOOP_BND */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_BND(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_BND(name, (cctkGH),'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_BND(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_BND(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_BND(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' istr)'),
+ (bsnl ' do {'),
+ (bsnl ' typedef int cctki3_loop[DIM]_bnd_##name;'),
+ (bsnl ' cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH);'),
+ (bsnl ' if (cctki3_cctkGH->cctk_dim != [DIM]) {'),
+ (bsnl ' _Pragma("omp critical")'),
+ (bsnl ' CCTK_WARN(CCTK_WARN_ABORT,'),
+ (bsnl ' "The macro CCTK_LOOP[DIM]_BND can only be used in [DIM] dimensions");'),
+ (bsnl ' }'),
+ (bsnl ' CCTK_INT cctki3_bndsize [[2*DIM]];'),
+ (bsnl ' CCTK_INT cctki3_is_ghostbnd[[2*DIM]];'),
+ (bsnl ' CCTK_INT cctki3_is_symbnd [[2*DIM]];'),
+ (bsnl ' CCTK_INT cctki3_is_physbnd [[2*DIM]];'),
+ (bsnl ' _Pragma("omp single copyprivate(cctki3_bndsize, cctki3_is_physbnd)")'),
+ (bsnl ' GetBoundarySizesAndTypes'),
+ (bsnl ' (cctki3_cctkGH, [2*DIM], cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd);'),
+ (bsnl ' CCTK_LOOP[DIM]STR_BOUNDARIES(name##_bnd,'),
+ (bsnl ' cctki3_cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt 'cctki3_bndsize[[2*I]]').','),
+ (bsnl ' '.(crpt 'cctki3_bndsize[[2*I+1]]').','),
+ (bsnl ' '.(crpt 'cctki3_is_physbnd[[2*I]]').','),
+ (bsnl ' '.(crpt 'cctki3_is_physbnd[[2*I+1]]').','),
+ (bsnl ' (istr)) {'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_BND(name)'),
+ (bsnl ' } CCTK_ENDLOOP[DIM]STR_BOUNDARIES(name##_bnd);'),
+ (bsnl ' typedef cctki3_loop[DIM]_bnd_##name cctki3_ensure_proper_nesting;'),
+ (bsnl ' } while (0)'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* LOOP_INTBND */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_INTBND(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_INTBND(name, (cctkGH),'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_INTBND(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_INTBND(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_INTBND(name, cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' istr)'),
+ (bsnl ' do {'),
+ (bsnl ' typedef int cctki3_loop[DIM]_intbnd_##name;'),
+ (bsnl ' cGH const *CCTK_RESTRICT const cctki3_cctkGH = (cctkGH);'),
+ (bsnl ' if (cctki3_cctkGH->cctk_dim != [DIM]) {'),
+ (bsnl ' _Pragma("omp critical")'),
+ (bsnl ' CCTK_WARN(CCTK_WARN_ABORT,'),
+ (bsnl ' "The macro CCTK_LOOP[DIM]_INTBND can only be used in [DIM] dimensions");'),
+ (bsnl ' }'),
+ (bsnl ' CCTK_INT cctki3_bndsize [[2*DIM]];'),
+ (bsnl ' CCTK_INT cctki3_is_ghostbnd[[2*DIM]];'),
+ (bsnl ' CCTK_INT cctki3_is_symbnd [[2*DIM]];'),
+ (bsnl ' CCTK_INT cctki3_is_physbnd [[2*DIM]];'),
+ (bsnl ' _Pragma("omp single copyprivate(cctki3_bndsize, cctki3_is_physbnd)")'),
+ (bsnl ' GetBoundarySizesAndTypes'),
+ (bsnl ' (cctki3_cctkGH, [2*DIM], cctki3_bndsize, cctki3_is_ghostbnd, cctki3_is_symbnd, cctki3_is_physbnd);'),
+ (bsnl ' CCTK_LOOP[DIM]STR_INTBOUNDARIES(name##_intbnd,'),
+ (bsnl ' cctki3_cctkGH,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'n[C]').','),
+ (bsnl ' '.(crpt 'cctki3_bndsize[[2*I]]').','),
+ (bsnl ' '.(crpt 'cctki3_bndsize[[2*I+1]]').','),
+ (bsnl ' '.(crpt 'cctki3_is_physbnd[[2*I]]').','),
+ (bsnl ' '.(crpt 'cctki3_is_physbnd[[2*I+1]]').','),
+ (bsnl ' (istr)) {'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_INTBND(name)'),
+ (bsnl ' } CCTK_ENDLOOP[DIM]STR_INTBOUNDARIES(name##_intbnd);'),
+ (bsnl ' typedef cctki3_loop[DIM]_intbnd_##name cctki3_ensure_proper_nesting;'),
+ (bsnl ' } while (0)'),
+ (nl ''),
+ (nl '#endif /* #ifdef CCODE */'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '#ifdef FCODE'),
+ (nl ''),
+ (nl '/* LOOP */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_DECLARE(name)'),
+ (bsnl ' && integer :: '.(crpt 'name/**/_[C]min')),
+ (bsnl ' && integer :: '.(crpt 'name/**/_[C]max')),
+ (bsnl ' && integer :: name/**/_istr'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_OMP_PRIVATE(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM](name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]min').','),
+ (bsnl ' '.(crpt '[C]max').','),
+ (bsnl ' '.(crpt '[C]lsh').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]min').','),
+ (bsnl ' '.(crpt '[C]max').','),
+ (bsnl ' '.(crpt '[C]lsh').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]min').','),
+ (bsnl ' '.(crpt '[C]max').','),
+ (bsnl ' '.(crpt '[C]lsh').','),
+ (bsnl ' istr)'),
+ (rpt (bsnl ' && name/**/_[C]min = [C]min')),
+ (rpt (bsnl ' && name/**/_[C]max = [C]max')),
+ (bsnl ' && name/**/_istr = istr'),
+ (reverse (rpt (bsnl ' && do [C] = name/**/_[C]min, name/**/_[C]max'))),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM](name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR(name)'),
+ (rpt (bsnl ' && end do')),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* LOOP_ALL */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_ALL_DECLARE(name)'),
+ (bsnl ' CCTK_LOOP[DIM]_DECLARE(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_ALL_OMP_PRIVATE(name)'),
+ (bsnl ' CCTK_LOOP[DIM]_OMP_PRIVATE(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_ALL(name,'),
+ (bsnl ' '.(crpt '[C]').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_ALL(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_ALL(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' istr)'),
+ (bsnl ' CCTK_LOOP[DIM]STR(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '1').','),
+ (bsnl ' '.(crpt 'CCTK_LSSH(0,[I+1])').','),
+ (bsnl ' '.(crpt 'cctk_lsh([I+1])').','),
+ (bsnl ' istr)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_ALL(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_ALL(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_ALL(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM](name)'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* LOOP_INTERIOR */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_INTERIOR_DECLARE(name)'),
+ (bsnl ' CCTK_LOOP[DIM]_DECLARE(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_INTERIOR_OMP_PRIVATE(name)'),
+ (bsnl ' CCTK_LOOP[DIM]_OMP_PRIVATE(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_INTERIOR(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_INTERIOR(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_INTERIOR(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').','),
+ (bsnl ' istr)'),
+ (bsnl ' CCTK_LOOP[DIM]STR(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '([C]blo)').','),
+ (rpt (bsnl ' CCTK_LSSH(0,[I+1])-([C]bhi),')),
+ (bsnl ' '.(crpt 'cctk_lsh([I+1])').','),
+ (bsnl ' istr)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_INTERIOR(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_INTERIOR(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_INTERIOR(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM](name)'),
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '/* LOOP_BOUNDARIES */'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_BOUNDARIES_DECLARE(name)'),
+ (bsnl ' CCTK_LOOP[DIM]_DECLARE(name)'),
+ (bsnl ' && integer :: lc_bmin([DIM]), lc_bmax([DIM])'),
+ (bsnl ' && integer :: lc_blo([DIM]), lc_bhi([DIM])'),
+ (bsnl ' && integer :: lc_istr'),
+ (bsnl ' && integer :: lc_dir, lc_face'),
+ (bsnl ' && integer :: lc_d'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_BOUNDARIES_OMP_PRIVATE(name)'),
+ (bsnl ' CCTK_LOOP[DIM]_OMP_PRIVATE(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]_BOUNDARIES(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').')'),
+ (bsnl ' CCTK_LOOP[DIM]STR_BOUNDARIES(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').','),
+ (bsnl ' 1)'),
+ (nl ''),
+ (bsnl '#define CCTK_LOOP[DIM]STR_BOUNDARIES(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt '[C]blo').','),
+ (bsnl ' '.(crpt '[C]bhi').','),
+ (bsnl ' istr)'),
+ (bsnl ' && lc_blo = (/ '.(crpt '[C]blo').' /)'),
+ (bsnl ' && lc_bhi = (/ '.(crpt '[C]bhi').' /)'),
+ (bsnl ' && lc_istr = istr'),
+ (bsnl ' && do lc_dir=1,[DIM]'),
+ (bsnl ' && do lc_face=1,2'),
+ (bsnl ' && do lc_d=1,[DIM]'),
+ (bsnl ' && lc_bmin(lc_d) = 1'),
+ (bsnl ' && lc_bmax(lc_d) = CCTK_LSSH(0,lc_d)'),
+ (bsnl ' && if (lc_d<lc_dir) then'),
+ (bsnl ' && lc_bmin(lc_d) = lc_bmin(lc_d)+lc_blo(lc_d)'),
+ (bsnl ' && lc_bmax(lc_d) = lc_bmax(lc_d)-lc_bhi(lc_d)'),
+ (bsnl ' && end if'),
+ (bsnl ' && end do'),
+ (bsnl ' && if (lc_face==1) then'),
+ (bsnl ' && lc_bmax(lc_dir) = lc_bmin(lc_dir)+lc_blo(lc_dir)'),
+ (bsnl ' && else'),
+ (bsnl ' && lc_bmin(lc_dir) = lc_bmax(lc_dir)-lc_bhi(lc_dir)'),
+ (bsnl ' && end if'),
+ (bsnl ' CCTK_LOOP[DIM]STR(name,'),
+ (bsnl ' '.(crpt '[C]').','),
+ (bsnl ' '.(crpt 'lc_bmin([I+1])').','),
+ (bsnl ' '.(crpt 'lc_bmax([I+1])').','),
+ (bsnl ' '.(crpt 'cctk_lsh([I+1])').','),
+ (bsnl ' lc_istr)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]_BOUNDARIES(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM]STR_BOUNDARIES(name)'),
+ (nl ''),
+ (bsnl '#define CCTK_ENDLOOP[DIM]STR_BOUNDARIES(name)'),
+ (bsnl ' CCTK_ENDLOOP[DIM](name)'),
+ (bsnl ' && end do /* face */'),
+ (bsnl ' && end do /* dir */'),
+ (nl ''),
+ (nl '#endif /* #ifdef FCODE */'),
+ );
+} # for dim
+
+
+
+# Output footer
+push @lines, (
+ (nl ''),
+ (nl ''),
+ (nl ''),
+ (nl '#endif /* #ifndef _CCTK_LOOP_H_ */'),
+ );
+
+
+
+# Write file
+open FILE, '>', 'cctk_Loop.h' or die;
+print FILE @lines;
+close FILE;
+
+print "Regenerated \"cctk_Loop.h\".\n";