IUOMKBDRBJNMDE7ZO2XXIGWD7GLQVAJI4I37K5IONSQVNV4HTF2QC
FEMASUBNU32NSG4DNXZX54CGCA57PVRGYO46L3A6F2EJ4BCSJ3SAC
IVHURSHY4636OGIF3PNDO5CWOVRLJ75M4LP65J6I2E6KAM4QKF4AC
WE6MDRN5SPK3THM4COLQFE3IUWBCQ5ZYUIAUCBJAZVEMMOVTNBOAC
722HZ7UFINNE3YKSYKP2NHZ5XEG5QQLQHSKC7PREJZR3EX6RDYUAC
PQB3EKQ6MBCXPTW4HB7SGMSTOTYMB3EFZX2573OFCQI6PSOEKCSQC
VAF66DTVLDWNG7N2PEQYEH4OH5SPSMFBXKPR2PU67IIM6CVPCJ7AC
BVR7DVINVPQG7PA6Z7QYVYNQ43YZL7XCC6AOMSMWMGAAB2Q43STAC
TOBGHRPKEPSXDN56WGSZNWOMCBVJ4KUSLWYWI56MC2RR3MM3KLZAC
// storage handling
namespace {
int GroupStorageCrease(const cGH *cctkGH, int n_groups, const int *groups,
const int *requested_tls, int *status, const bool inc) {
DECLARE_CCTK_PARAMETERS;
assert(cctkGH);
assert(n_groups >= 0);
assert(groups);
assert(requested_tls);
for (int n = 0; n < n_groups; ++n) {
if (groups[n] < 0 or groups[n] >= CCTK_NumGroups()) {
CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
"Group index %d is illegal", groups[n]);
return -1;
}
assert(groups[n] >= 0 and groups[n] < CCTK_NumGroups());
assert(requested_tls[n] >= 0 or requested_tls[n] == -1);
}
// sanitize list of requested timelevels
std::vector<int> tls(n_groups);
for (int n = 0; n < n_groups; ++n) {
int ntls = requested_tls[n];
int const declared_tls = CCTK_DeclaredTimeLevelsGI(groups[n]);
if (inc and declared_tls < 2 and ntls > declared_tls) {
char *groupname = CCTK_GroupName(groups[n]);
CCTK_VWarn(CCTK_WARN_ALERT, __LINE__, __FILE__, CCTK_THORNSTRING,
"Attempting to activate %d timelevels for group '%s' which "
"only has a single timelevel declared in interface.ccl. "
"Please declared at least 2 timelevels in interface.ccl to "
"allow more timelevels to be created at runtime.",
ntls, groupname);
free(groupname);
ntls = declared_tls;
}
if (ntls == -1) {
ntls = declared_tls;
}
tls.at(n) = ntls;
}
// TODO: actually do something
int min_num_timelevels = INT_MAX;
for (int n = 0; n < n_groups; ++n) {
int const gid = groups[n];
cGroup group;
int ierr = CCTK_GroupData(gid, &group);
assert(not ierr);
// Record previous number of allocated time levels
if (status) {
// Note: This remembers only the last level
status[n] = group.numtimelevels;
}
// Record (minimum of) current number of time levels
min_num_timelevels = min(min_num_timelevels, group.numtimelevels);
} // for n
if (min_num_timelevels == INT_MAX) {
min_num_timelevels = 0;
}
return min_num_timelevels;
}
}
int GroupStorageIncrease(const cGH *cctkGH, int n_groups, const int *groups,
const int *tls, int *status) {
DECLARE_CCTK_PARAMETERS
return GroupStorageCrease(cctkGH, n_groups, groups, tls, status, true);
}
int GroupStorageDecrease(const cGH *cctkGH, int n_groups, const int *groups,
const int *tls, int *status) {
DECLARE_CCTK_PARAMETERS
return GroupStorageCrease(cctkGH, n_groups, groups, tls, status, false);
}
int EnableGroupStorage(const cGH *cctkGH, const char *groupname) {
const int group = CCTK_GroupIndex(groupname);
assert(group >= 0 and group < CCTK_NumGroups());
// TODO: decide whether to use CCTK_MaxActiveTimeLevelsGI
const int tls = CCTK_DeclaredTimeLevelsGI(group);
int status;
GroupStorageIncrease(cctkGH, 1, &group, &tls, &status);
// Return whether storage was allocated previously
return status;
}
int DisableGroupStorage(const cGH *cctkGH, const char *groupname) {
const int group = CCTK_GroupIndex(groupname);
assert(group >= 0 and group < CCTK_NumGroups());
const int tls = 0;
int status;
GroupStorageDecrease(cctkGH, 1, &group, &tls, &status);
// Return whether storage was allocated previously
return status;
}
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);