use of gov.sandia.n2a.language.Operator in project n2a by frothga.
the class ExportJob method genericPart.
public void genericPart(MPart part, Element result, String... skip) {
EquationSet partEquations = getEquations(part);
List<Element> resultElements = new ArrayList<Element>();
List<String> skipList = Arrays.asList(skip);
for (MNode c : part) {
MPart p = (MPart) c;
String key = p.key();
// Skip connection bindings. They are unpacked elsewhere.
if (partEquations.findConnection(key) != null)
continue;
if (key.startsWith("$"))
continue;
if (skipList.contains(key))
continue;
if (p.isPart()) {
genericPart(p, resultElements);
} else {
// We need to check two things:
// * Has the variable been overridden after it was declared in the base part?
// * Is it an expression or a constant?
// An override that is an expression should trigger a LEMS extension part.
// A constant that is either overridden or required should be emitted here.
boolean expression = true;
String value = p.get();
Variable v = partEquations.find(new Variable(key));
try {
// This could convert an expression to a constant.
Type evalue = v.eval(context);
// TODO: if it is a simple AccessVariable, then it shouldn't be viewed as an expression.
Operator op = Operator.parse(value);
if (op instanceof Constant) {
// "direct" value
Type dvalue = ((Constant) op).value;
expression = !evalue.equals(dvalue);
}
} catch (Exception e) {
}
boolean overridden = p.isFromTopDocument() || isOverride(part.get("$inherit").replace("\"", ""), key);
String name = sequencer.bestFieldName(result, p.get("$metadata", "backend.lems.param"));
if (name.isEmpty())
name = key;
boolean required = sequencer.isRequired(result, name);
if (required || (overridden && !expression)) {
// biophysicalUnits() should return strings (non-numbers) unmodified
result.setAttribute(name, biophysicalUnits(p.get()));
}
}
}
sequencer.append(result, resultElements);
}
use of gov.sandia.n2a.language.Operator in project n2a by frothga.
the class JobC method prepareStaticObjects.
public void prepareStaticObjects(Operator op, final CRenderer context, final String pad) throws Exception {
Visitor visitor = new Visitor() {
public boolean visit(Operator op) {
if (op instanceof Output) {
Output o = (Output) op;
if (// column name is generated
o.operands.length < 3) {
String stringName = stringNames.get(op);
BackendDataC bed = (BackendDataC) context.part.backendData;
if (context.global ? bed.needGlobalPath : bed.needLocalPath) {
context.result.append(pad + "path (" + stringName + ");\n");
context.result.append(pad + stringName + " += \"." + o.variableName + "\";\n");
} else {
context.result.append(pad + stringName + " = \"" + o.variableName + "\";\n");
}
} else if (// mode flags are present
o.operands.length > 3) {
if (o.operands[0] instanceof Constant) {
// Detect raw flag
Operator op3 = o.operands[3];
if (op3 instanceof Constant) {
if (op3.toString().contains("raw")) {
String outputName = outputNames.get(o.operands[0].toString());
context.result.append(pad + outputName + "->raw = true;\n");
}
}
}
}
// Continue to drill down, because I/O functions can be nested.
return true;
}
if (op instanceof Input) {
Input i = (Input) op;
if (i.operands[0] instanceof Constant) {
String inputName = inputNames.get(i.operands[0].toString());
if (!context.global) {
context.result.append(pad + inputName + "->epsilon = " + resolve(context.bed.dt.reference, context, false) + " / 1000;\n");
}
// Detect time flag
String mode = "";
if (i.operands.length > 3) {
// just assuming it's a constant string
mode = i.operands[3].toString();
} else if (i.operands[1] instanceof Constant) {
Constant c = (Constant) i.operands[1];
if (c.value instanceof Text)
mode = c.toString();
}
if (mode.contains("time")) {
context.result.append(pad + inputName + "->time = true;\n");
}
}
return true;
}
return true;
}
};
op.visit(visitor);
}
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"));
if (p == null)
return;
if (p.equations.size() != 1)
return;
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))
return;
if (!((AccessVariable) variable).name.equals("$t"))
return;
// Method 1 -- check for reference to simple value, for example a "duration" parameter
if (value instanceof AccessVariable) {
AccessVariable av = (AccessVariable) value;
Variable v = av.reference.variable;
if (v.equations.size() == 1) {
EquationEntry e = v.equations.first();
if (e.condition == null && e.expression instanceof Constant) {
metadata.set(e.expression.getDouble(), "duration");
return;
}
}
}
// Method 2 -- try to calculate the value
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)
metadata.set(((Scalar) result).value, "duration");
}
use of gov.sandia.n2a.language.Operator in project n2a by frothga.
the class EquationSet method dumpMedians.
/**
* @return true if we should abort the run. false if it is OK to proceed.
*/
public boolean dumpMedians(PrintStream ps, ExponentContext context) {
boolean result = false;
class VisitorExponentSanity implements Visitor {
boolean sane = true;
boolean warningExp = false;
boolean warningPow = false;
public boolean visit(Operator op) {
if (op instanceof AccessVariable)
return sane;
String name = op.toString();
if (op instanceof Function)
name += "()";
else
name = "operator" + name;
if (op.center < 0 || op.center > Operator.MSB) {
sane = false;
String flow = op.center < 0 ? "underflow" : "overflow";
ps.println("\t\t ERROR: " + name + " produces " + flow + " (center = " + op.center + ")");
} else if (Math.abs(op.exponent) > 128) {
ps.println("\t\t WARNING: " + name + " produces large exponent (" + op.exponent + ")");
} else if (op instanceof Exp) {
Exp e = (Exp) op;
if (!warningExp && (e.operands.length < 2 || !e.operands[1].getString().contains("median"))) {
ps.println("\t\t WARNING: exp() is very sensitive. If input values vary far from 0, provide a hint for median output value.");
warningExp = true;
}
} else if (op instanceof Power) {
Power p = (Power) op;
if (!warningPow && (p.hint == null || !p.hint.contains("median"))) {
if (p.hint == null)
ps.println("\t\t WARNING: operator^ is very sensitive. For best results, use pow() and provide a hint for median output value.");
else
ps.println("\t\t WARNING: pow() is very sensitive. For best results, provide a hint for median output value.");
warningPow = true;
}
}
return sane;
}
}
;
VisitorExponentSanity visitor = new VisitorExponentSanity();
for (Variable v : variables) {
if (v.hasAttribute("dummy"))
continue;
// Must abort run, because numbers will almost certainly go out of range.
if (v.center < 0 || v.center > Operator.MSB)
result = true;
// No need to warn about large v.exponent, because the user will be able to view the list.
// Convert center power to an approximate decimal value.
int centerPower = v.exponent - Operator.MSB + v.center;
int base10 = (int) Math.floor(centerPower / b2d);
ps.println(" " + base10 + "\t" + v.exponent + "\t" + v.fullName());
if (context.overflows.contains(v))
ps.println("\t\t WARNING: Magnitude did not converge. Add hint (median=median_absolute_value).");
visitor.sane = true;
visitor.warningExp = false;
visitor.warningPow = false;
v.visit(visitor);
if (!visitor.sane)
result = true;
}
for (EquationSet s : parts) if (s.dumpMedians(ps, context))
result = true;
return result;
}
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 implements 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