use of gov.sandia.n2a.language.Operator in project n2a by frothga.
the class EquationSet method determineDuration.
/**
* Infers length of simulation based on contents of equation set, particularly
* an expression for top-level $p that involves $t.
* Depends on results of: determineTypes() -- to set up Variable.type member with usable values
*/
public void determineDuration() {
Variable p = find(new Variable("$p", 0));
if (p != null && p.equations.size() == 1) {
Operator expression = p.equations.first().expression;
Operator variable = null;
Operator value = null;
if (// only true if expression is not null
expression instanceof LT || expression instanceof LE) {
OperatorBinary comparison = (OperatorBinary) expression;
variable = comparison.operand0;
value = comparison.operand1;
} else if (expression instanceof GT || expression instanceof GE) {
OperatorBinary comparison = (OperatorBinary) expression;
variable = comparison.operand1;
value = comparison.operand0;
}
if (variable instanceof AccessVariable && ((AccessVariable) variable).name.equals("$t")) {
Instance instance = new Instance() {
// all AccessVariable objects will reach here first, and get back the Variable.type field
public Type get(VariableReference r) throws EvaluationException {
return r.variable.type;
}
};
Type result = value.eval(instance);
if (result instanceof Scalar)
setNamedValue("duration", new Double(((Scalar) result).value).toString());
}
}
}
use of gov.sandia.n2a.language.Operator in project n2a by frothga.
the class EquationSet method findInitOnlyRecursive.
public boolean findInitOnlyRecursive() {
boolean changed = false;
for (EquationSet s : parts) {
if (s.findInitOnlyRecursive())
changed = true;
}
ReplaceInit replaceInit = new ReplaceInit();
for (final Variable v : variables) {
// Note: some variables get tagged "initOnly" by other means, so don't re-process
if (v.hasAny(new String[] { "initOnly", "constant", "dummy" }))
continue;
// Count equations
int firesDuringInit = 0;
int firesDuringUpdate = 0;
// If we have a single update equation, then we may still be initOnly if it depends only on constants or other initOnly variables. Save the update equation for analysis.
EquationEntry update = null;
for (EquationEntry e : v.equations) {
if (e.condition == null) {
firesDuringInit++;
firesDuringUpdate++;
update = e;
} else {
// init
replaceInit.init = 1;
replaceInit.live = 1;
Operator test = e.condition.deepCopy().transform(replaceInit).simplify(v);
boolean fires = true;
if (test instanceof Constant) {
Constant c = (Constant) test;
if (c.value instanceof Scalar && ((Scalar) c.value).value == 0)
fires = false;
}
if (fires)
firesDuringInit++;
// update
replaceInit.init = 0;
replaceInit.live = 1;
test = e.condition.deepCopy().transform(replaceInit).simplify(v);
fires = true;
if (test instanceof Constant) {
Constant c = (Constant) test;
if (c.value instanceof Scalar && ((Scalar) c.value).value == 0)
fires = false;
}
if (fires) {
firesDuringUpdate++;
update = e;
}
}
}
if (firesDuringUpdate == 0) {
if (firesDuringInit > 0 && v.derivative == null) {
v.addAttribute("initOnly");
changed = true;
}
} else if (// last chance to be "initOnly": must be exactly one equation that is not a combining operator
firesDuringUpdate == 1 && v.assignment == Variable.REPLACE) {
// Determine if our single update equation depends only on constants and initOnly variables
class VisitInitOnly extends Visitor {
// until something falsifies it
boolean isInitOnly = true;
public boolean visit(Operator op) {
if (isInitOnly) {
if (op instanceof AccessVariable) {
AccessVariable av = (AccessVariable) op;
// constant has already been replaced. Therefore, only the "initOnly" attribute matters here.
if (av.reference == null || av.reference.variable == null)
isInitOnly = false;
Variable r = av.reference.variable;
if (!r.hasAttribute("initOnly"))
isInitOnly = false;
// Also verify that the variables we depend on are available during the appropriate phase of init
if (// Note that temporaries are always available.
isInitOnly && !r.hasAttribute("temporary")) {
if (// we are a $variable, so we can only depend on $index and $init
v.name.startsWith("$")) {
if (!"$index,$init,$live".contains(r.name))
isInitOnly = false;
} else // we are a regular variable, so can only depend on $variables
{
if (!r.name.startsWith("$"))
isInitOnly = false;
}
}
} else if (op instanceof Function) {
Function f = (Function) op;
if (!f.canBeInitOnly())
isInitOnly = false;
}
}
return isInitOnly;
}
}
VisitInitOnly visitor = new VisitInitOnly();
if (update.condition != null)
update.condition.visit(visitor);
if (visitor.isInitOnly) {
update.expression.visit(visitor);
if (visitor.isInitOnly) {
v.addAttribute("initOnly");
changed = true;
}
}
}
if (firesDuringUpdate > 0 && v.derivative != null && !v.hasAttribute("initOnly"))
v.addAttribute("updates");
else
v.removeAttribute("updates");
}
return changed;
}
use of gov.sandia.n2a.language.Operator in project n2a by frothga.
the class EquationSet method dump.
public String dump(boolean showNamespace, String prefix) {
Renderer renderer;
if (showNamespace) {
class Prefixer extends Renderer {
public boolean render(Operator op) {
if (!(op instanceof AccessVariable))
return false;
AccessVariable av = (AccessVariable) op;
if (av.reference == null || av.reference.variable == null) {
result.append("<unresolved!>" + av.name);
} else {
result.append("<" + av.reference.variable.container.prefix() + ">" + av.reference.variable.nameString());
}
return true;
}
}
renderer = new Prefixer();
} else {
renderer = new Renderer();
}
renderer.result.append(prefix + name + "\n");
prefix = prefix + " ";
if (connectionBindings != null) {
for (ConnectionBinding c : connectionBindings) {
renderer.result.append(prefix + c.alias + " = ");
EquationSet s = c.endpoint;
if (showNamespace) {
renderer.result.append("<");
if (s.container != null) {
renderer.result.append(s.container.prefix());
}
renderer.result.append(">");
}
renderer.result.append(s.name + "\n");
}
}
for (Variable v : variables) {
if (// If no equations, then this is an implicit variable, so no need to list here.
v.equations.size() > 0) {
renderer.result.append(prefix + v.nameString());
renderer.result.append(" =" + v.combinerString());
if (v.equations.size() == 1) {
renderer.result.append(" ");
v.equations.first().render(renderer);
renderer.result.append("\n");
} else {
renderer.result.append("\n");
for (EquationEntry e : v.equations) {
renderer.result.append(prefix + " ");
e.render(renderer);
renderer.result.append("\n");
}
}
}
}
for (EquationSet e : parts) {
renderer.result.append(e.dump(showNamespace, prefix));
}
return renderer.result.toString();
}
use of gov.sandia.n2a.language.Operator in project n2a by frothga.
the class EquationSet method findLethalVariables.
public void findLethalVariables() {
for (EquationSet s : parts) {
s.findLethalVariables();
}
// Determine if $n can decrease
Variable n = find(new Variable("$n"));
if (n != null) {
for (EquationEntry e : n.equations) {
// Even if each expression is constant, $n could still change during operation if it is a multi-conditional.
if (e.condition != null && !(e.condition instanceof Constant)) {
lethalN = true;
break;
}
if (!(e.expression instanceof Constant)) {
lethalN = true;
break;
}
}
}
// Determine if $p has an assignment less than 1
Variable p = find(new Variable("$p"));
if (p != null) {
// Determine if any equation is capable of setting $p to something besides 1
ReplaceInit replaceInit = new ReplaceInit();
for (EquationEntry e : p.equations) {
if (e.expression instanceof Constant) {
Type value = ((Constant) e.expression).value;
if (value instanceof Scalar) {
if (((Scalar) value).value == 1.0)
continue;
}
}
// Check if condition fires during init phase
if (e.condition != null) {
replaceInit.init = 1;
replaceInit.live = 1;
Operator test = e.condition.deepCopy().transform(replaceInit).simplify(p);
if (test instanceof Constant) {
Constant c = (Constant) test;
if (// Does not fire during init phase
c.value instanceof Scalar && ((Scalar) c.value).value == 0) {
// Check if condition fires during update phase
replaceInit.init = 0;
test = e.condition.deepCopy().transform(replaceInit).simplify(p);
if (test instanceof Constant) {
c = (Constant) test;
// Does not fire during update phase
if (c.value instanceof Scalar && ((Scalar) c.value).value == 0)
continue;
}
}
}
}
lethalP = true;
break;
}
}
// Determine if any splits kill this part
for (// my splits are the parts I can split into
ArrayList<EquationSet> split : // my splits are the parts I can split into
splits) {
if (!split.contains(this)) {
lethalType = true;
break;
}
}
}
use of gov.sandia.n2a.language.Operator in project n2a by frothga.
the class EquationSet method determineTraceVariableName.
public void determineTraceVariableName() {
for (EquationSet s : parts) {
s.determineTraceVariableName();
}
class TraceVisitor extends Visitor {
public Variable v;
public boolean visit(Operator op) {
if (op instanceof Output) {
((Output) op).determineVariableName(v);
return false;
}
return true;
}
}
TraceVisitor visitor = new TraceVisitor();
for (Variable v : variables) {
visitor.v = v;
v.visit(visitor);
}
}
Aggregations