Search in sources :

Example 6 with AccessVariable

use of gov.sandia.n2a.language.AccessVariable in project n2a by frothga.

the class Output method isStringExpression.

/**
 *        Determines if the given operator is a string expression.
 *        This is the case if any operator it depends on is a string.
 *        If an operand is a variable, then its equations must contain a string.
 */
public static boolean isStringExpression(Variable v, Operator op) {
    class StringVisitor extends Visitor {

        boolean foundString;

        Variable from;

        public StringVisitor(Variable from) {
            this.from = from;
            from.visited = null;
        }

        public boolean visit(Operator op) {
            if (op instanceof Constant) {
                Constant c = (Constant) op;
                if (c.value instanceof Text)
                    foundString = true;
                return false;
            }
            if (op instanceof AccessVariable) {
                AccessVariable av = (AccessVariable) op;
                Variable v = av.reference.variable;
                // Prevent infinite recursion
                Variable p = from;
                while (p != null) {
                    if (p == v)
                        return false;
                    p = p.visited;
                }
                v.visited = from;
                from = v;
                v.visit(this);
                from = v.visited;
                return false;
            }
            // no reason to dig any further
            if (foundString)
                return false;
            // Add is the only operator that can propagate string values. All other operators and functions return scalars or matrices.
            return op instanceof Add;
        }
    }
    StringVisitor visitor = new StringVisitor(v);
    op.visit(visitor);
    return visitor.foundString;
}
Also used : Operator(gov.sandia.n2a.language.Operator) Add(gov.sandia.n2a.language.operator.Add) AccessVariable(gov.sandia.n2a.language.AccessVariable) Variable(gov.sandia.n2a.eqset.Variable) AccessVariable(gov.sandia.n2a.language.AccessVariable) Visitor(gov.sandia.n2a.language.Visitor) Constant(gov.sandia.n2a.language.Constant) Text(gov.sandia.n2a.language.type.Text)

Example 7 with AccessVariable

use of gov.sandia.n2a.language.AccessVariable in project n2a by frothga.

the class XyceBackend method generateNetlist.

public void generateNetlist(MNode job, Simulator simulator, FileWriter writer) throws Exception {
    Population toplevel = (Population) simulator.wrapper.valuesObject[0];
    XyceRenderer renderer = new XyceRenderer(simulator);
    // Header
    writer.append(toplevel.equations.name + "\n");
    writer.append("\n");
    writer.append("* seed: " + job.get("$metadata", "seed") + "\n");
    writer.append(".tran 0 " + job.get("$metadata", "duration") + "\n");
    // Equations
    for (Instance i : simulator) {
        if (i == simulator.wrapper)
            continue;
        writer.append("\n");
        writer.append("* " + i + "\n");
        renderer.pi = i;
        renderer.exceptions = null;
        XyceBackendData bed = (XyceBackendData) i.equations.backendData;
        if (bed.deviceSymbol != null) {
            writer.append(bed.deviceSymbol.getDefinition(renderer));
        }
        InstanceTemporaries temp = new InstanceTemporaries(i, simulator, false, bed.internal);
        for (final Variable v : i.equations.variables) {
            // Compute variable v
            // TODO: how to switch between multiple conditions that can be true during normal operation? IE: how to make Xyce code conditional?
            // Perhaps gate each condition (through a transistor?) and sum them at a single node.
            // e can be null
            EquationEntry e = v.select(temp);
            Symbol def = bed.equationSymbols.get(e);
            if (def == null)
                continue;
            writer.append(def.getDefinition(renderer));
            // Trace
            class TraceFinder extends Visitor {

                List<Operator> traces = new ArrayList<Operator>();

                public boolean visit(Operator op) {
                    if (op instanceof Output) {
                        traces.add(((Output) op).operands[0]);
                        return false;
                    }
                    return true;
                }
            }
            TraceFinder traceFinder = new TraceFinder();
            e.expression.visit(traceFinder);
            for (Operator trace : traceFinder.traces) {
                // We don't know if contents is .func, expression or a node, so always wrap in braces.
                writer.append(".print tran {");
                if (trace instanceof AccessVariable) {
                    AccessVariable av = (AccessVariable) trace;
                    writer.append(renderer.change(av.reference));
                } else // trace is an expression
                {
                    if (// this trace wraps the entire equation
                    e.expression instanceof Output && ((Output) e.expression).operands[0] == trace) {
                        // simply print the LHS variable, similar to the AccessVariable case above
                        writer.append(renderer.change(v.reference));
                    } else {
                        // arbitrary expression
                        writer.append(renderer.change(trace));
                    }
                }
                // one .print line per variable
                writer.append("}\n");
            }
        }
    }
    // Trailer
    writer.append(".end\n");
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) Variable(gov.sandia.n2a.eqset.Variable) Visitor(gov.sandia.n2a.language.Visitor) AccessVariable(gov.sandia.n2a.language.AccessVariable) Instance(gov.sandia.n2a.language.type.Instance) Symbol(gov.sandia.n2a.backend.xyce.netlist.Symbol) InstanceTemporaries(gov.sandia.n2a.backend.internal.InstanceTemporaries) XyceRenderer(gov.sandia.n2a.backend.xyce.netlist.XyceRenderer) Output(gov.sandia.n2a.language.function.Output) Population(gov.sandia.n2a.backend.internal.Population) ArrayList(java.util.ArrayList) List(java.util.List) EquationEntry(gov.sandia.n2a.eqset.EquationEntry)

Example 8 with AccessVariable

use of gov.sandia.n2a.language.AccessVariable in project n2a by frothga.

the class XyceRenderer method render.

public boolean render(Operator op) {
    if (op instanceof AccessVariable) {
        AccessVariable av = (AccessVariable) op;
        result.append(change(av.reference));
        return true;
    }
    // IE: they are not an ongoing source of randomness during execution.
    if (op instanceof Uniform) {
        Uniform u = (Uniform) op;
        if (u.operands.length > 0) {
            int dimension = (int) Math.round(((Scalar) u.operands[0].eval(pi)).value);
            if (dimension != 1)
                System.err.println("WARNING: Xyce does not support multivariate form of uniform()");
        }
        result.append("rand()");
        return true;
    }
    if (op instanceof Gaussian) {
        Gaussian g = (Gaussian) op;
        if (g.operands.length > 0) {
            int dimension = (int) Math.round(((Scalar) g.operands[0].eval(pi)).value);
            if (dimension != 1)
                System.err.println("WARNING: Xyce does not support multivariate form of gaussian()");
        }
        result.append("agauss(0,6,6)");
        return true;
    }
    if (op instanceof Power) {
        Power p = (Power) op;
        result.append("(");
        p.operand0.render(this);
        result.append(") ** (");
        p.operand1.render(this);
        result.append(")");
        return true;
    }
    return false;
}
Also used : AccessVariable(gov.sandia.n2a.language.AccessVariable) Uniform(gov.sandia.n2a.language.function.Uniform) Gaussian(gov.sandia.n2a.language.function.Gaussian) Power(gov.sandia.n2a.language.operator.Power) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 9 with AccessVariable

use of gov.sandia.n2a.language.AccessVariable in project n2a by frothga.

the class EquationSet method resolveConnectionBindings.

/**
 *        Scan for equations that look and smell like connection bindings.
 *        A binding equation has these characteristics:
 *        <ul>
 *        <li>Only one equation on the variable.
 *        <li>Unconditional (conditional bindings are not permitted)
 *        <li>No operators, only a name on RHS that appears like a variable name.
 *        <li>Both LHS and RHS are order 0 (not derivatives)
 *        <li>No variable in the current equation set matches the name.
 *        </ul>
 *        $up is permitted. The explicit name of a higher container may also be used.
 *        $connect should not appear. It should have been overwritten during construction.
 *        If $connect does appear, bindings are incomplete, which is an error.
 */
public void resolveConnectionBindings(LinkedList<String> unresolved) throws Exception {
    // need to use an iterator here, so we can remove variables from the set
    Iterator<Variable> it = variables.iterator();
    while (it.hasNext()) {
        Variable v = it.next();
        // Detect instance variables
        if (v.order > 0)
            continue;
        if (v.equations.size() != 1)
            continue;
        if (v.assignment != Variable.REPLACE)
            continue;
        EquationEntry ee = v.equations.first();
        if (ee.condition != null)
            continue;
        if (!(ee.expression instanceof AccessVariable))
            continue;
        AccessVariable av = (AccessVariable) ee.expression;
        if (av.getOrder() > 0)
            continue;
        if (find(new Variable(av.getName())) != null)
            continue;
        // Resolve connection endpoint to a specific equation set
        ConnectionBinding result = new ConnectionBinding();
        if (!resolveConnectionBinding(av.name, result)) {
            // Only report simple names here, to minimize confusion.
            if (!av.name.contains("."))
                unresolved.add(prefix() + "." + v.nameString() + " --> " + av.name);
            continue;
        }
        // Could be a variable or prefix referring to an already-found connection.
        if (result.endpoint == null)
            continue;
        // Store connection binding
        if (connectionBindings == null)
            connectionBindings = new ArrayList<ConnectionBinding>();
        result.alias = v.name;
        result.index = connectionBindings.size();
        connectionBindings.add(result);
        result.endpoint.connected = true;
        // Should no longer be in the equation list, as there is nothing further to compute.
        it.remove();
    }
    // The population reached in the first descent needs to be tracked.
    if (connectionBindings != null) {
        for (ConnectionBinding c : connectionBindings) {
            int last = c.resolution.size() - 1;
            for (int i = 1; i < last; i++) {
                Object o0 = c.resolution.get(i - 1);
                if (!(o0 instanceof EquationSet))
                    continue;
                Object o1 = c.resolution.get(i);
                if (!(o1 instanceof EquationSet))
                    continue;
                Object o2 = c.resolution.get(i + 1);
                if (!(o2 instanceof EquationSet))
                    continue;
                EquationSet s0 = (EquationSet) o0;
                EquationSet s1 = (EquationSet) o1;
                EquationSet s2 = (EquationSet) o2;
                if (// double descent
                s1.container == s0 && s2.container == s1) {
                    s1.needInstanceTracking = true;
                }
            }
        }
    }
    // Descend to child parts after resolving parent. This order is necessary to support nested connections.
    for (EquationSet s : parts) {
        s.resolveConnectionBindings(unresolved);
    }
}
Also used : AccessVariable(gov.sandia.n2a.language.AccessVariable) AccessVariable(gov.sandia.n2a.language.AccessVariable) ArrayList(java.util.ArrayList)

Example 10 with AccessVariable

use of gov.sandia.n2a.language.AccessVariable 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());
        }
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) AccessVariable(gov.sandia.n2a.language.AccessVariable) Instance(gov.sandia.n2a.language.type.Instance) LT(gov.sandia.n2a.language.operator.LT) GT(gov.sandia.n2a.language.operator.GT) OperatorBinary(gov.sandia.n2a.language.OperatorBinary) Scalar(gov.sandia.n2a.language.type.Scalar) Type(gov.sandia.n2a.language.Type) LE(gov.sandia.n2a.language.operator.LE) GE(gov.sandia.n2a.language.operator.GE)

Aggregations

AccessVariable (gov.sandia.n2a.language.AccessVariable)16 Operator (gov.sandia.n2a.language.Operator)12 Variable (gov.sandia.n2a.eqset.Variable)7 Scalar (gov.sandia.n2a.language.type.Scalar)7 ArrayList (java.util.ArrayList)6 Constant (gov.sandia.n2a.language.Constant)5 Visitor (gov.sandia.n2a.language.Visitor)5 TreeSet (java.util.TreeSet)5 EquationSet (gov.sandia.n2a.eqset.EquationSet)4 Type (gov.sandia.n2a.language.Type)4 VariableReference (gov.sandia.n2a.eqset.VariableReference)3 Instance (gov.sandia.n2a.language.type.Instance)3 ConnectionBinding (gov.sandia.n2a.eqset.EquationSet.ConnectionBinding)2 Transformer (gov.sandia.n2a.language.Transformer)2 Output (gov.sandia.n2a.language.function.Output)2 Text (gov.sandia.n2a.language.type.Text)2 InstanceTemporaries (gov.sandia.n2a.backend.internal.InstanceTemporaries)1 Population (gov.sandia.n2a.backend.internal.Population)1 Symbol (gov.sandia.n2a.backend.xyce.netlist.Symbol)1 XyceRenderer (gov.sandia.n2a.backend.xyce.netlist.XyceRenderer)1