#ifndef SCHEDULE_HXX
#define SCHEDULE_HXX
#include "driver.hxx"
#include "loop.hxx"
#include <cctk.h>
#include <cctk_Schedule.h>
#include <algorithm>
#include <array>
#include <cassert>
#include <optional>
namespace CarpetX {
using namespace std;
using namespace Loop;
int Initialise(tFleshConfig *config);
int Evolve(tFleshConfig *config);
int Shutdown(tFleshConfig *config);
int SyncGroupsByDirI(const cGH *restrict cctkGH, int numgroups,
const int *groups, const int *directions);
int CallFunction(void *function, cFunctionData *attribute, void *data);
int GroupStorageIncrease(const cGH *cctkGH, int n_groups, const int *groups,
const int *tls, int *status);
int GroupStorageDecrease(const cGH *cctkGH, int n_groups, const int *groups,
const int *tls, int *status);
int EnableGroupStorage(const cGH *cctkGH, const char *groupname);
int DisableGroupStorage(const cGH *cctkGH, const char *groupname);
extern cGH *saved_cctkGH;
struct active_levels_t {
int min_level, max_level;
active_levels_t() = delete;
active_levels_t(const int min_level, const int max_level)
: min_level(min_level), max_level(max_level) {
assert(min_level >= 0);
assert(max_level <= int(ghext->leveldata.size()));
}
template <typename F> void loop(F f) {
for (int level = min_level; level < max_level; ++level)
assert(ghext->leveldata.at(level).iteration ==
ghext->leveldata.at(min_level).iteration);
for (int level = min_level; level < max_level; ++level)
f(ghext->leveldata.at(level));
}
template <typename F> void loop_reverse(F f) {
for (int level = min_level; level < max_level; ++level)
assert(ghext->leveldata.at(level).iteration ==
ghext->leveldata.at(min_level).iteration);
for (int level = max_level - 1; level >= min_level; --level)
f(ghext->leveldata.at(level));
}
};
extern optional<active_levels_t> active_levels;
struct MFPointer {
int m_index;
amrex::Box m_fabbox;
amrex::Box m_growntilebox;
amrex::Box m_validbox;
amrex::IntVect m_nGrowVect;
MFPointer() = delete;
MFPointer(const MFPointer &) = default;
MFPointer(MFPointer &&) = default;
MFPointer &operator=(const MFPointer &) = default;
MFPointer &operator=(MFPointer &&) = default;
MFPointer(const amrex::MFIter &mfi)
: m_index(mfi.index()), m_fabbox(mfi.fabbox()),
m_growntilebox(mfi.growntilebox()), m_validbox(mfi.validbox()),
m_nGrowVect(mfi.theFabArrayBase().nGrowVect()) {}
constexpr int index() const noexcept { return m_index; }
constexpr amrex::Box fabbox() const noexcept { return m_fabbox; }
constexpr amrex::Box growntilebox() const noexcept { return m_growntilebox; }
constexpr amrex::Box validbox() const noexcept { return m_validbox; }
constexpr amrex::IntVect nGrowVect() const noexcept { return m_nGrowVect; }
};
struct GridDesc : GridDescBase {
GridDesc() = delete;
GridDesc(const GHExt::LevelData &leveldata, const MFPointer &mfp);
GridDesc(const cGH *cctkGH) : GridDescBase(cctkGH) {}
};
struct GridPtrDesc : GridDesc {
amrex::Dim3 cactus_offset;
GridPtrDesc() = delete;
GridPtrDesc(const GHExt::LevelData &leveldata, const MFPointer &mfp);
template <typename T> T *ptr(const amrex::Array4<T> &vars, int vi) const {
return vars.ptr(cactus_offset.x, cactus_offset.y, cactus_offset.z, vi);
}
template <typename T>
T &idx(const amrex::Array4<T> &vars, int i, int j, int k, int vi) const {
return vars(cactus_offset.x + i, cactus_offset.y + i, cactus_offset.z + j,
vi);
}
};
struct GridPtrDesc1 : GridDesc {
amrex::Dim3 cactus_offset;
array<int, dim> gimin, gimax;
array<int, dim> gash;
GridPtrDesc1() = delete;
GridPtrDesc1(const GridPtrDesc1 &) = delete;
GridPtrDesc1 &operator=(const GridPtrDesc1 &) = delete;
GridPtrDesc1(const GHExt::LevelData::GroupData &groupdata,
const MFPointer &mfp);
template <typename T> T *ptr(const amrex::Array4<T> &vars, int vi) const {
return vars.ptr(cactus_offset.x + gimin[0], cactus_offset.y + gimin[1],
cactus_offset.z + gimin[2], vi);
}
template <typename T>
T &idx(const amrex::Array4<T> &vars, int i, int j, int k, int vi) const {
return vars(cactus_offset.x + gimin[0] + i, cactus_offset.y + gimin[1] + i,
cactus_offset.z + gimin[2] + j, vi);
}
template <typename T>
GF3D1<T> gf3d(const amrex::Array4<T> &vars, int vi) const {
return GF3D1<T>(ptr(vars, vi), gimin, gimax, gash);
}
};
bool in_local_mode(const cGH *restrict cctkGH);
bool in_level_mode(const cGH *restrict cctkGH);
bool in_global_mode(const cGH *restrict cctkGH);
bool in_meta_mode(const cGH *restrict cctkGH);
void error_if_invalid(const GHExt::LevelData ::GroupData &grouppdata, int vi,
int tl, const valid_t &required,
const function<string()> &msg);
void warn_if_invalid(const GHExt::LevelData ::GroupData &grouppdata, int vi,
int tl, const valid_t &required,
const function<string()> &msg);
void poison_invalid(const GHExt::LevelData::GroupData &groupdata, int vi,
int tl);
void check_valid(const GHExt::LevelData::GroupData &groupdata, int vi, int tl,
const function<string()> &msg);
void error_if_invalid(const GHExt::GlobalData::ArrayGroupData &groupdata,
int vi, int tl, const valid_t &required,
const function<string()> &msg);
void warn_if_invalid(const GHExt::GlobalData::ArrayGroupData &groupdata,
int vi, int tl, const valid_t &required,
const function<string()> &msg);
void poison_invalid(const GHExt::GlobalData::ArrayGroupData &groupdata, int vi,
int tl);
void check_valid(const GHExt::GlobalData::ArrayGroupData &groupdata, int vi,
int tl, const function<string()> &msg);
}
#endif