Search in sources :

Example 1 with Constant

use of gov.sandia.n2a.language.Constant 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 Constant

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

the class EquationSet method getInit.

public boolean getInit() {
    Variable init = find(new Variable("$init"));
    if (init == null)
        return false;
    EquationEntry e = init.equations.first();
    return ((Scalar) ((Constant) e.expression).value).value == 1.0;
}
Also used : AccessVariable(gov.sandia.n2a.language.AccessVariable) Constant(gov.sandia.n2a.language.Constant)

Example 3 with Constant

use of gov.sandia.n2a.language.Constant 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 Constant

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

the class JobC method generateStatic.

public void generateStatic(final EquationSet s, final StringBuilder result) {
    for (EquationSet p : s.parts) generateStatic(p, result);
    // Generate static definitions
    final BackendDataC bed = (BackendDataC) s.backendData;
    class CheckStatic extends Visitor {

        public boolean global;

        public boolean visit(Operator op) {
            if (op instanceof Constant) {
                Type m = ((Constant) op).value;
                if (m instanceof Matrix) {
                    Matrix A = (Matrix) m;
                    int rows = A.rows();
                    int cols = A.columns();
                    String matrixName = "Matrix" + matrixNames.size();
                    matrixNames.put(op, matrixName);
                    if (rows == 3 && cols == 1)
                        result.append("Vector3 " + matrixName + " = Matrix<float>");
                    else
                        result.append("Matrix<float> " + matrixName);
                    result.append(" (\"" + A + "\");\n");
                }
                // Don't try to descend tree from here
                return false;
            }
            if (op instanceof Function) {
                Function f = (Function) op;
                if (// We need to auto-generate the column name.
                f instanceof Output && f.operands.length < 3) {
                    String stringName = "columnName" + stringNames.size();
                    stringNames.put(op, stringName);
                    if (global) {
                        bed.setGlobalNeedPath(s);
                        bed.globalColumns.add(stringName);
                    } else {
                        bed.setLocalNeedPath(s);
                        bed.localColumns.add(stringName);
                    }
                }
                // Detect functions that need static handles
                if (f.operands.length > 0) {
                    Operator operand0 = f.operands[0];
                    if (operand0 instanceof Constant) {
                        Constant c = (Constant) operand0;
                        Type o = c.value;
                        if (o instanceof Text) {
                            String fileName = ((Text) o).value;
                            if (op instanceof ReadMatrix) {
                                if (!matrixNames.containsKey(fileName)) {
                                    String matrixName = "Matrix" + matrixNames.size();
                                    matrixNames.put(fileName, matrixName);
                                    result.append("MatrixInput * " + matrixName + " = matrixHelper (\"" + fileName + "\");\n");
                                }
                            } else if (f instanceof Input) {
                                if (!inputNames.containsKey(fileName)) {
                                    String inputName = "Input" + inputNames.size();
                                    inputNames.put(fileName, inputName);
                                    result.append("InputHolder * " + inputName + " = inputHelper (\"" + fileName + "\");\n");
                                }
                            } else if (f instanceof Output) {
                                if (!outputNames.containsKey(fileName)) {
                                    String outputName = "Output" + outputNames.size();
                                    outputNames.put(fileName, outputName);
                                    result.append("OutputHolder * " + outputName + " = outputHelper (\"" + fileName + "\");\n");
                                }
                            }
                        }
                    } else // Dynamic file name (no static handle)
                    {
                        if (f instanceof ReadMatrix) {
                            matrixNames.put(op, "Matrix" + matrixNames.size());
                            stringNames.put(operand0, "fileName" + stringNames.size());
                        } else if (f instanceof Input) {
                            inputNames.put(op, "Input" + inputNames.size());
                            stringNames.put(operand0, "fileName" + stringNames.size());
                        } else if (f instanceof Output) {
                            outputNames.put(op, "Output" + outputNames.size());
                            stringNames.put(operand0, "fileName" + stringNames.size());
                        }
                    }
                }
                // Functions could be nested, so continue descent.
                return true;
            }
            return true;
        }
    }
    CheckStatic checkStatic = new CheckStatic();
    for (Variable v : s.ordered) {
        checkStatic.global = v.hasAttribute("global");
        v.visit(checkStatic);
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator) EquationSet(gov.sandia.n2a.eqset.EquationSet) 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) ReadMatrix(gov.sandia.n2a.language.function.ReadMatrix) Function(gov.sandia.n2a.language.Function) Type(gov.sandia.n2a.language.Type) Input(gov.sandia.n2a.language.function.Input) ReadMatrix(gov.sandia.n2a.language.function.ReadMatrix) BuildMatrix(gov.sandia.n2a.language.BuildMatrix) Matrix(gov.sandia.n2a.language.type.Matrix) Output(gov.sandia.n2a.language.function.Output)

Example 5 with Constant

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

the class InternalBackendData method analyzeEvents.

public static void analyzeEvents(final EquationSet s, final List<EventTarget> eventTargets, final List<Variable> eventReferences) {
    class EventVisitor extends Visitor {

        public boolean found;

        public boolean visit(Operator op) {
            if (op instanceof Event) {
                found = true;
                Event de = (Event) op;
                if (// this event has not yet been analyzed
                de.eventType == null) {
                    final EventTarget et = new EventTarget(de);
                    int targetIndex = eventTargets.indexOf(et);
                    if (// event target already exists
                    targetIndex >= 0) {
                        de.eventType = eventTargets.get(targetIndex);
                    } else // we must create a new event target, or more properly, fill in the event target we just used as a query object
                    {
                        // Create an entry and save the index
                        targetIndex = eventTargets.size();
                        eventTargets.add(et);
                        de.eventType = et;
                        et.container = s;
                        // Determine edge type
                        if (de.operands.length < 3) {
                            et.edge = EventTarget.RISE;
                        } else if (de.operands[2] instanceof Constant) {
                            Constant c = (Constant) de.operands[2];
                            if (c.value instanceof Text) {
                                Text t = (Text) c.value;
                                if (t.value.equalsIgnoreCase("nonzero"))
                                    et.edge = EventTarget.NONZERO;
                                else if (t.value.equalsIgnoreCase("change"))
                                    et.edge = EventTarget.CHANGE;
                                else if (t.value.equalsIgnoreCase("fall"))
                                    et.edge = EventTarget.FALL;
                                else
                                    et.edge = EventTarget.RISE;
                            } else {
                                Backend.err.get().println("ERROR: event() edge type must be a string.");
                                throw new Backend.AbortRun();
                            }
                        } else {
                            Backend.err.get().println("ERROR: event() edge type must be constant.");
                            throw new Backend.AbortRun();
                        }
                        // Allocate auxiliary variable
                        if (de.operands[0] instanceof AccessVariable) {
                            AccessVariable av = (AccessVariable) de.operands[0];
                            VariableReference reference = av.reference;
                            Variable v = reference.variable;
                            // then the user has broken the rule that we can't see temporaries in other parts.
                            if (v.hasAttribute("temporary") && v.container != s) {
                                Backend.err.get().println("WARNING: Cannot be temporary due to event monitor: " + v.container.name + "." + v.nameString() + " from " + s.name);
                                v.removeAttribute("temporary");
                            }
                            // so fall through to the !trackOne case below.
                            if (!v.hasAttribute("temporary")) {
                                // ensure it's buffered, so we can detect change
                                v.addAttribute("externalRead");
                                et.trackOne = true;
                                // just a holder for the reference
                                et.track = new Variable();
                                et.track.reference = reference;
                            }
                        }
                        if (// Expression, so create auxiliary variable. Aux not needed for NONZERO, because no change detection.
                        !et.trackOne && et.edge != EventTarget.NONZERO) {
                            et.track = new Variable("eventAux" + targetIndex, 0);
                            et.track.type = new Scalar(0);
                            et.track.reference = new VariableReference();
                            et.track.reference.variable = et.track;
                        }
                        // Locate any temporaries for evaluation. TODO: for more efficiency, we could have separate lists of temporaries for the condition and delay operands
                        // Tie into the dependency graph using a phantom variable (which can go away afterward without damaging the graph).
                        final Variable phantom = new Variable("event");
                        phantom.uses = new IdentityHashMap<Variable, Integer>();
                        for (int i = 0; i < et.event.operands.length; i++) et.event.operands[i].visit(new Visitor() {

                            public boolean visit(Operator op) {
                                if (op instanceof AccessVariable) {
                                    AccessVariable av = (AccessVariable) op;
                                    Variable v = av.reference.variable;
                                    if (!phantom.uses.containsKey(v))
                                        phantom.uses.put(v, 1);
                                    return false;
                                }
                                return true;
                            }
                        });
                        // Scan all variables in equation set to see if we need them
                        for (Variable t : s.variables) {
                            if (t.hasAttribute("temporary") && phantom.dependsOn(t) != null)
                                et.dependencies.add(t);
                        }
                        // Note the default is already set to -1 (no care)
                        class DelayVisitor extends Visitor {

                            TreeSet<EquationSet> containers = new TreeSet<EquationSet>();

                            public boolean visit(Operator op) {
                                if (op instanceof AccessVariable) {
                                    AccessVariable av = (AccessVariable) op;
                                    // could include the target part itself, if in fact we use local variables
                                    containers.add(av.reference.variable.container);
                                    return false;
                                }
                                return true;
                            }
                        }
                        DelayVisitor dv = new DelayVisitor();
                        if (de.operands.length >= 2) {
                            if (de.operands[1] instanceof Constant) {
                                Constant c = (Constant) de.operands[1];
                                et.delay = (float) ((Scalar) c.value).value;
                                if (et.delay < 0)
                                    et.delay = -1;
                            } else {
                                // indicates that we need to evaluate delay at run time
                                et.delay = -2;
                                de.operands[1].visit(dv);
                            }
                        }
                        // Set up monitors in source parts
                        class ConditionVisitor extends Visitor {

                            TreeSet<EquationSet> containers = new TreeSet<EquationSet>();

                            public boolean visit(Operator op) {
                                if (op instanceof AccessVariable) {
                                    AccessVariable av = (AccessVariable) op;
                                    Variable v = av.reference.variable;
                                    EquationSet sourceContainer = v.container;
                                    containers.add(sourceContainer);
                                    // Set up monitors for values that can vary during update.
                                    if (!v.hasAttribute("constant") && !v.hasAttribute("initOnly") && !et.monitors(sourceContainer)) {
                                        EventSource es = new EventSource(sourceContainer, et);
                                        // null means self-reference, a special case handled in Part
                                        if (sourceContainer != s)
                                            es.reference = av.reference;
                                        et.sources.add(es);
                                    }
                                    return false;
                                }
                                return true;
                            }
                        }
                        ConditionVisitor cv = new ConditionVisitor();
                        de.operands[0].visit(cv);
                        // Special case for event with no references that vary
                        if (et.sources.isEmpty()) {
                            // We can avoid creating a self monitor if we know for certain that the event will never fire
                            boolean neverFires = false;
                            if (de.operands[0] instanceof Constant) {
                                if (et.edge == EventTarget.NONZERO) {
                                    Type op0 = ((Constant) de.operands[0]).value;
                                    if (op0 instanceof Scalar) {
                                        neverFires = ((Scalar) op0).value == 0;
                                    } else {
                                        Backend.err.get().println("ERROR: Condition for event() must resolve to a number.");
                                        throw new Backend.AbortRun();
                                    }
                                } else {
                                    neverFires = true;
                                }
                            }
                            if (!neverFires) {
                                EventSource es = new EventSource(s, et);
                                // This is a self-reference, so es.reference should be null.
                                et.sources.add(es);
                            }
                        }
                        // Determine if monitor needs to test every target, or if one representative target is sufficient
                        for (EventSource source : et.sources) {
                            // associated with any given source instance, so every target must be evaluated separately.
                            if (cv.containers.size() > 1)
                                source.testEach = true;
                            if (dv.containers.size() > 1 || (dv.containers.size() == 1 && dv.containers.first() != source.container))
                                source.delayEach = true;
                        }
                    }
                }
            }
            return true;
        }
    }
    EventVisitor eventVisitor = new EventVisitor();
    for (Variable v : s.variables) {
        eventVisitor.found = false;
        v.visit(eventVisitor);
        if ((eventVisitor.found || v.dependsOnEvent()) && v.reference.variable != v)
            eventReferences.add(v);
    }
}
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) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar) TreeSet(java.util.TreeSet) EquationSet(gov.sandia.n2a.eqset.EquationSet) AccessVariable(gov.sandia.n2a.language.AccessVariable) VariableReference(gov.sandia.n2a.eqset.VariableReference) Text(gov.sandia.n2a.language.type.Text) Backend(gov.sandia.n2a.plugins.extpoints.Backend) Type(gov.sandia.n2a.language.Type) Event(gov.sandia.n2a.language.function.Event)

Aggregations

Constant (gov.sandia.n2a.language.Constant)19 Operator (gov.sandia.n2a.language.Operator)14 AccessVariable (gov.sandia.n2a.language.AccessVariable)11 Scalar (gov.sandia.n2a.language.type.Scalar)10 Type (gov.sandia.n2a.language.Type)9 Text (gov.sandia.n2a.language.type.Text)6 Visitor (gov.sandia.n2a.language.Visitor)5 EquationSet (gov.sandia.n2a.eqset.EquationSet)4 Variable (gov.sandia.n2a.eqset.Variable)4 ParseException (gov.sandia.n2a.language.ParseException)3 Input (gov.sandia.n2a.language.function.Input)3 Output (gov.sandia.n2a.language.function.Output)3 BuildMatrix (gov.sandia.n2a.language.BuildMatrix)2 Function (gov.sandia.n2a.language.Function)2 ReadMatrix (gov.sandia.n2a.language.function.ReadMatrix)2 Add (gov.sandia.n2a.language.operator.Add)2 TreeSet (java.util.TreeSet)2 MNode (gov.sandia.n2a.db.MNode)1 ConnectionBinding (gov.sandia.n2a.eqset.EquationSet.ConnectionBinding)1 MPart (gov.sandia.n2a.eqset.MPart)1