Search in sources :

Example 1 with Scalar

use of gov.sandia.n2a.language.type.Scalar in project n2a by frothga.

the class EquationSet method addSpecials.

/**
 *        Add variables to equation set that are needed, but that the user should not normally define.
 *        Depends on results of: none
 */
public void addSpecials() {
    for (EquationSet s : parts) {
        s.addSpecials();
    }
    // force $init to exist
    setInit(0);
    Variable v = new Variable("$t", 0);
    if (add(v)) {
        v.equations = new TreeSet<EquationEntry>();
    }
    // $t'
    v = new Variable("$t", 1);
    if (add(v)) {
        v.equations = new TreeSet<EquationEntry>();
    }
    if (// top-level model
    container == null) {
        // must have a termination condition
        v = new Variable("$p", 0);
        if (// but it doesn't
        add(v)) {
            try {
                // limit sim time to 1 second, if not otherwise specified
                String duration = getNamedValue("duration", "1");
                v.add(new EquationEntry("$t<" + duration));
            } catch (Exception parseError) {
                try {
                    v.add(new EquationEntry("$t<1"));
                }// This exception should never happen. We simply want to silence Java about it.
                 catch (Exception parseError2) {
                }
            }
        }
    }
    // $live functions much the same as $init. See setInit().
    v = new Variable("$live", 0);
    if (add(v)) {
        // default. Actual values should be set by setAttributeLive()
        v.addAttribute("constant");
        EquationEntry e = new EquationEntry(v, "");
        e.expression = new Constant(new Scalar(1));
        v.add(e);
    }
    v = new Variable("$type", 0);
    if (add(v)) {
        v.equations = new TreeSet<EquationEntry>();
    }
    if (connected || connectionBindings == null) {
        v = new Variable("$index", 0);
        if (add(v)) {
            // most backends will set $index before processing init equations
            v.addAttribute("initOnly");
            v.equations = new TreeSet<EquationEntry>();
        } else {
            v = find(v);
        }
        // Force $index to exist for connection targets. Used for anti-indexing into list of instances.
        if (connected)
            v.addUser(this);
        v = new Variable("$n", 0);
        if (add(v)) {
            // default. Actual values set by client code.
            v.addAttribute("constant");
            EquationEntry e = new EquationEntry(v, "");
            e.expression = new Constant(new Scalar(1));
            v.add(e);
        }
    }
}
Also used : AccessVariable(gov.sandia.n2a.language.AccessVariable) Constant(gov.sandia.n2a.language.Constant) EvaluationException(gov.sandia.n2a.language.EvaluationException) ParseException(gov.sandia.n2a.language.ParseException) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 2 with Scalar

use of gov.sandia.n2a.language.type.Scalar in project n2a by frothga.

the class EquationSet method resolveRHS.

public void resolveRHS(LinkedList<String> unresolved) {
    for (EquationSet s : parts) {
        s.resolveRHS(unresolved);
    }
    class Resolver extends Transformer {

        public Variable from;

        public LinkedList<String> unresolved;

        public String fromName() {
            String result = from.container.prefix();
            if (!result.isEmpty())
                result += ".";
            return result + from.nameString();
        }

        public Operator transform(Operator op) {
            if (op instanceof AccessVariable) {
                AccessVariable av = (AccessVariable) op;
                Variable query = new Variable(av.getName(), av.getOrder());
                query.reference = new VariableReference();
                EquationSet dest = resolveEquationSet(query, false);
                if (dest == null) {
                    unresolved.add(av.name + "\t" + fromName());
                } else {
                    query.reference.variable = dest.find(query);
                    if (query.reference.variable == null) {
                        if (query.name.equals("(connection)")) {
                            // create a phantom variable.  TODO: should this be an attribute instead?
                            query.reference.variable = new Variable("(connection)");
                            // the container itself is really the target
                            query.reference.variable.container = dest;
                            // because instance variables are bound before the part is put into service, and remain constant for its entire life
                            query.reference.variable.addAttribute("initOnly");
                            // TODO: when $connect() is implemented, instances should become first class variables in the equation set, and this circular reference will be created by resolveLHS()
                            query.reference.variable.reference = query.reference;
                        } else if (// accountable endpoint
                        query.name.equals("$count")) {
                            if (dest.accountableConnections == null)
                                dest.accountableConnections = new TreeSet<AccountableConnection>();
                            String alias = av.name.split("\\.", 2)[0];
                            AccountableConnection ac = new AccountableConnection(EquationSet.this, alias);
                            if (!dest.accountableConnections.add(ac))
                                ac = dest.accountableConnections.floor(ac);
                            if (ac.count == null) {
                                // Create a fully-functional variable.
                                // However, it never gets formally added to dest, because dest should never evaluate it.
                                // Rather, it is maintained by the backend's connection system.
                                ac.count = new Variable(prefix() + ".$count");
                                ac.count.type = new Scalar(0);
                                ac.count.container = dest;
                                ac.count.equations = new TreeSet<EquationEntry>();
                                query.reference.variable = ac.count;
                                query.reference.variable.reference = query.reference;
                            } else {
                                query.reference.variable = ac.count;
                            }
                        } else {
                            unresolved.add(av.name + "\t" + fromName());
                        }
                    } else {
                        Variable target = query.reference.variable;
                        from.addDependencyOn(target);
                        if (from.container != target.container) {
                            target.addAttribute("externalRead");
                            if (target.hasAttribute("temporary")) {
                                Backend.err.get().println("WARNING: Variable " + target.container.prefix() + "." + target.nameString() + " has an external read, so cannot be temporary.");
                                target.removeAttribute("temporary");
                            }
                        }
                    }
                }
                av.reference = query.reference;
                return av;
            }
            if (op instanceof Split) {
                Split split = (Split) op;
                int count = split.names.length;
                split.parts = new ArrayList<EquationSet>(count);
                for (int i = 0; i < count; i++) {
                    String temp = split.names[i];
                    EquationSet part = container.parts.floor(new EquationSet(temp));
                    if (part.name.equals(temp))
                        split.parts.add(part);
                    else
                        unresolved.add(temp + "\t" + fromName());
                }
            }
            return null;
        }
    }
    Resolver resolver = new Resolver();
    for (Variable v : variables) {
        resolver.from = v;
        resolver.unresolved = unresolved;
        v.transform(resolver);
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator) AccessVariable(gov.sandia.n2a.language.AccessVariable) Transformer(gov.sandia.n2a.language.Transformer) AccessVariable(gov.sandia.n2a.language.AccessVariable) LinkedList(java.util.LinkedList) Scalar(gov.sandia.n2a.language.type.Scalar) TreeSet(java.util.TreeSet) Split(gov.sandia.n2a.language.Split)

Example 3 with Scalar

use of gov.sandia.n2a.language.type.Scalar in project n2a by frothga.

the class EquationSet method setInit.

/**
 *        Change the value of the constant $init in the current equation set.
 *        Used to indicate if we are in the init phase or not.
 */
public void setInit(float value) {
    Variable init = find(new Variable("$init"));
    if (init == null) {
        init = new Variable("$init", 0);
        // TODO: should really be "initOnly", since it changes value during (at the end of) the init cycle.
        init.addAttribute("constant");
        EquationEntry e = new EquationEntry(init, "");
        e.expression = new Constant(new Scalar(value));
        init.add(e);
        add(init);
    } else {
        EquationEntry e = init.equations.first();
        ((Scalar) ((Constant) e.expression).value).value = value;
    }
}
Also used : AccessVariable(gov.sandia.n2a.language.AccessVariable) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 4 with Scalar

use of gov.sandia.n2a.language.type.Scalar in project n2a by frothga.

the class AccessVariable method simplify.

public Operator simplify(Variable from) {
    // unresolved!
    if (reference == null || reference.variable == null)
        return this;
    Variable v = reference.variable;
    // specifically prevent $init and $live from being replaced by a Constant
    if (v.name.equals("$init") || v.name.equals("$live"))
        return this;
    // A variable may locally evaluate to a constant, yet be subject to change from outside equations.
    if (v.hasAttribute("externalWrite"))
        return this;
    if (v.equations.size() != 1)
        return this;
    EquationEntry e = v.equations.first();
    if (e.expression == null)
        return this;
    if (e.condition != null) {
        if (!(e.condition instanceof Constant))
            return this;
        // Check for nonzero constant
        Type value = ((Constant) e.condition).value;
        // This second condition should be eliminated by Variable.simplify(), but until it is, don't do anything here.
        if (!(value instanceof Scalar) || ((Scalar) value).value == 0)
            return this;
    }
    if (e.expression instanceof Constant) {
        from.removeDependencyOn(v);
        from.changed = true;
        return e.expression;
    }
    // Attempt to simplify expression, and maybe get a Constant
    Variable p = from;
    while (p != null) {
        // can't simplify, because we've already visited this variable
        if (p == v)
            return this;
        p = p.visited;
    }
    v.visited = from;
    e.expression = e.expression.simplify(v);
    if (e.expression instanceof Constant) {
        from.removeDependencyOn(v);
        from.changed = true;
        return e.expression;
    }
    if (// Our variable is simply an alias for another variable, so grab the other variable instead.
    e.expression instanceof AccessVariable) {
        AccessVariable av = (AccessVariable) e.expression;
        Variable v2 = av.reference.variable;
        if (v2 == v)
            return this;
        // Can't reference a temporary outside the current equation set.
        if (v2.hasAttribute("temporary") && v2.container != from.container)
            return this;
        // Note: Folding an aliased variable will very likely remove one or more steps of delay in the movement of values through an equation set.
        // This might go against the user's intention. The folding can be blocked by adding a condition
        reference = av.reference;
        name = av.reference.variable.nameString();
        from.removeDependencyOn(v);
        from.addDependencyOn(v2);
        from.changed = true;
    }
    return this;
}
Also used : Variable(gov.sandia.n2a.eqset.Variable) EquationEntry(gov.sandia.n2a.eqset.EquationEntry) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 5 with Scalar

use of gov.sandia.n2a.language.type.Scalar in project n2a by frothga.

the class BuildMatrix method eval.

public Type eval(Instance context) throws EvaluationException {
    int columns = operands.length;
    if (columns == 0)
        return new MatrixDense();
    int rows = operands[0].length;
    if (rows == 0)
        return new MatrixDense();
    Matrix result = new MatrixDense(rows, columns);
    for (int c = 0; c < columns; c++) {
        for (int r = 0; r < rows; r++) {
            if (operands[c][r] == null) {
                result.set(r, c, 0);
            } else {
                Type o = operands[c][r].eval(context);
                if (o instanceof Scalar)
                    result.set(r, c, ((Scalar) o).value);
                else if (o instanceof Text)
                    result.set(r, c, Double.valueOf(((Text) o).value));
                else if (o instanceof Matrix)
                    result.set(r, c, ((Matrix) o).get(0, 0));
                else
                    throw new EvaluationException("Can't construct matrix element from the given type.");
            }
        }
    }
    return result;
}
Also used : Matrix(gov.sandia.n2a.language.type.Matrix) MatrixDense(gov.sandia.n2a.language.type.MatrixDense) Text(gov.sandia.n2a.language.type.Text) Scalar(gov.sandia.n2a.language.type.Scalar)

Aggregations

Scalar (gov.sandia.n2a.language.type.Scalar)42 Type (gov.sandia.n2a.language.Type)17 AccessVariable (gov.sandia.n2a.language.AccessVariable)14 Variable (gov.sandia.n2a.eqset.Variable)13 Matrix (gov.sandia.n2a.language.type.Matrix)11 Constant (gov.sandia.n2a.language.Constant)10 Operator (gov.sandia.n2a.language.Operator)10 Text (gov.sandia.n2a.language.type.Text)8 EquationSet (gov.sandia.n2a.eqset.EquationSet)6 ArrayList (java.util.ArrayList)6 Simulator (gov.sandia.n2a.backend.internal.Simulator)5 Instance (gov.sandia.n2a.language.type.Instance)5 MatrixDense (gov.sandia.n2a.language.type.MatrixDense)5 TreeSet (java.util.TreeSet)5 EventSource (gov.sandia.n2a.backend.internal.InternalBackendData.EventSource)4 EventTarget (gov.sandia.n2a.backend.internal.InternalBackendData.EventTarget)4 EquationEntry (gov.sandia.n2a.eqset.EquationEntry)3 VariableReference (gov.sandia.n2a.eqset.VariableReference)3 ConnectionBinding (gov.sandia.n2a.eqset.EquationSet.ConnectionBinding)2 EvaluationException (gov.sandia.n2a.language.EvaluationException)2