use bigint instead of int for timestep related variable functions to avoid overflows

This commit is contained in:
Axel Kohlmeyer
2020-10-01 09:35:45 -04:00
parent ea3af3c2bc
commit 8c56f60939

View File

@ -2687,23 +2687,23 @@ double Variable::collapse_tree(Tree *tree)
}
if (tree->type == STAGGER) {
int ivalue1 = static_cast<int> (collapse_tree(tree->first));
int ivalue2 = static_cast<int> (collapse_tree(tree->second));
bigint ivalue1 = static_cast<bigint> (collapse_tree(tree->first));
bigint ivalue2 = static_cast<bigint> (collapse_tree(tree->second));
if (tree->first->type != VALUE || tree->second->type != VALUE) return 0.0;
tree->type = VALUE;
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2)
error->one(FLERR,"Invalid math function in variable formula");
int lower = update->ntimestep/ivalue1 * ivalue1;
int delta = update->ntimestep - lower;
bigint lower = update->ntimestep/ivalue1 * ivalue1;
bigint delta = update->ntimestep - lower;
if (delta < ivalue2) tree->value = lower+ivalue2;
else tree->value = lower+ivalue1;
return tree->value;
}
if (tree->type == LOGFREQ) {
int ivalue1 = static_cast<int> (collapse_tree(tree->first));
int ivalue2 = static_cast<int> (collapse_tree(tree->second));
int ivalue3 = static_cast<int> (collapse_tree(tree->extra[0]));
bigint ivalue1 = static_cast<bigint> (collapse_tree(tree->first));
bigint ivalue2 = static_cast<bigint> (collapse_tree(tree->second));
bigint ivalue3 = static_cast<bigint> (collapse_tree(tree->extra[0]));
if (tree->first->type != VALUE || tree->second->type != VALUE ||
tree->extra[0]->type != VALUE) return 0.0;
tree->type = VALUE;
@ -2711,9 +2711,9 @@ double Variable::collapse_tree(Tree *tree)
error->one(FLERR,"Invalid math function in variable formula");
if (update->ntimestep < ivalue1) tree->value = ivalue1;
else {
int lower = ivalue1;
bigint lower = ivalue1;
while (update->ntimestep >= ivalue3*lower) lower *= ivalue3;
int multiple = update->ntimestep/lower;
bigint multiple = update->ntimestep/lower;
if (multiple < ivalue2) tree->value = (multiple+1)*lower;
else tree->value = lower*ivalue3;
}
@ -2721,9 +2721,9 @@ double Variable::collapse_tree(Tree *tree)
}
if (tree->type == LOGFREQ2) {
int ivalue1 = static_cast<int> (collapse_tree(tree->first));
int ivalue2 = static_cast<int> (collapse_tree(tree->second));
int ivalue3 = static_cast<int> (collapse_tree(tree->extra[0]));
bigint ivalue1 = static_cast<bigint> (collapse_tree(tree->first));
bigint ivalue2 = static_cast<bigint> (collapse_tree(tree->second));
bigint ivalue3 = static_cast<bigint> (collapse_tree(tree->extra[0]));
if (tree->first->type != VALUE || tree->second->type != VALUE ||
tree->extra[0]->type != VALUE) return 0.0;
tree->type = VALUE;
@ -2733,7 +2733,7 @@ double Variable::collapse_tree(Tree *tree)
else {
tree->value = ivalue1;
double delta = ivalue1*(ivalue3-1.0)/ivalue2;
int count = 0;
bigint count = 0;
while (update->ntimestep >= tree->value) {
tree->value += delta;
count++;
@ -2745,9 +2745,9 @@ double Variable::collapse_tree(Tree *tree)
}
if (tree->type == LOGFREQ3) {
int ivalue1 = static_cast<int> (collapse_tree(tree->first));
int ivalue2 = static_cast<int> (collapse_tree(tree->second));
int ivalue3 = static_cast<int> (collapse_tree(tree->extra[0]));
bigint ivalue1 = static_cast<bigint> (collapse_tree(tree->first));
bigint ivalue2 = static_cast<bigint> (collapse_tree(tree->second));
bigint ivalue3 = static_cast<bigint> (collapse_tree(tree->extra[0]));
if (tree->first->type != VALUE || tree->second->type != VALUE ||
tree->extra[0]->type != VALUE) return 0.0;
tree->type = VALUE;
@ -2760,7 +2760,7 @@ double Variable::collapse_tree(Tree *tree)
tree->value = ivalue1;
double logsp = ivalue1;
double factor = pow(((double)ivalue3)/ivalue1, 1.0/(ivalue2-1));
int linsp = ivalue1;
bigint linsp = ivalue1;
while (update->ntimestep >= (tree->value)) {
logsp *= factor;
linsp++;
@ -2774,9 +2774,9 @@ double Variable::collapse_tree(Tree *tree)
}
if (tree->type == STRIDE) {
int ivalue1 = static_cast<int> (collapse_tree(tree->first));
int ivalue2 = static_cast<int> (collapse_tree(tree->second));
int ivalue3 = static_cast<int> (collapse_tree(tree->extra[0]));
bigint ivalue1 = static_cast<bigint> (collapse_tree(tree->first));
bigint ivalue2 = static_cast<bigint> (collapse_tree(tree->second));
bigint ivalue3 = static_cast<bigint> (collapse_tree(tree->extra[0]));
if (tree->first->type != VALUE || tree->second->type != VALUE ||
tree->extra[0]->type != VALUE) return 0.0;
tree->type = VALUE;
@ -2784,7 +2784,7 @@ double Variable::collapse_tree(Tree *tree)
error->one(FLERR,"Invalid math function in variable formula");
if (update->ntimestep < ivalue1) tree->value = ivalue1;
else if (update->ntimestep < ivalue2) {
int offset = update->ntimestep - ivalue1;
bigint offset = update->ntimestep - ivalue1;
tree->value = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
if (tree->value > ivalue2) tree->value = (double) MAXBIGINT;
} else tree->value = (double) MAXBIGINT;
@ -2792,12 +2792,12 @@ double Variable::collapse_tree(Tree *tree)
}
if (tree->type == STRIDE2) {
int ivalue1 = static_cast<int> (collapse_tree(tree->first));
int ivalue2 = static_cast<int> (collapse_tree(tree->second));
int ivalue3 = static_cast<int> (collapse_tree(tree->extra[0]));
int ivalue4 = static_cast<int> (collapse_tree(tree->extra[1]));
int ivalue5 = static_cast<int> (collapse_tree(tree->extra[2]));
int ivalue6 = static_cast<int> (collapse_tree(tree->extra[3]));
bigint ivalue1 = static_cast<bigint> (collapse_tree(tree->first));
bigint ivalue2 = static_cast<bigint> (collapse_tree(tree->second));
bigint ivalue3 = static_cast<bigint> (collapse_tree(tree->extra[0]));
bigint ivalue4 = static_cast<bigint> (collapse_tree(tree->extra[1]));
bigint ivalue5 = static_cast<bigint> (collapse_tree(tree->extra[2]));
bigint ivalue6 = static_cast<bigint> (collapse_tree(tree->extra[3]));
if (tree->first->type != VALUE || tree->second->type != VALUE ||
tree->extra[0]->type != VALUE || tree->extra[1]->type != VALUE ||
tree->extra[2]->type != VALUE || tree->extra[3]->type != VALUE)
@ -2813,15 +2813,15 @@ double Variable::collapse_tree(Tree *tree)
if (update->ntimestep < ivalue1) istep = ivalue1;
else if (update->ntimestep < ivalue2) {
if (update->ntimestep < ivalue4 || update->ntimestep > ivalue5) {
int offset = update->ntimestep - ivalue1;
bigint offset = update->ntimestep - ivalue1;
istep = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
if (update->ntimestep < ivalue2 && istep > ivalue4)
tree->value = ivalue4;
} else {
int offset = update->ntimestep - ivalue4;
bigint offset = update->ntimestep - ivalue4;
istep = ivalue4 + (offset/ivalue6)*ivalue6 + ivalue6;
if (istep > ivalue5) {
int offset = ivalue5 - ivalue1;
bigint offset = ivalue5 - ivalue1;
istep = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
if (istep > ivalue2) istep = MAXBIGINT;
}