Search in sources :

Example 11 with Instance

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

the class EquationSet method determineTypesEval.

public boolean determineTypesEval() {
    boolean changed = false;
    for (final Variable v : variables) {
        if (v.hasAttribute("constant"))
            continue;
        // Don't change type for certain $variables.
        if (v.name.equals("$init") || v.name.equals("$live") || v.name.equals("$p") || v.name.equals("$n") || (v.name.equals("$t") && v.order == 1))
            continue;
        Type value = null;
        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;
            }
        };
        for (EquationEntry e : v.equations) {
            // However, scanning them all increase our chance of propagating correct values.
            try {
                Type temp = e.expression.eval(instance);
                if (value == null || temp.betterThan(value))
                    value = temp;
            }// This can happen due to type mismatch, and may be a temporary condition while values are propagating.
             catch (Exception x) {
            }
        }
        if (v.derivative != null) {
            if (value == null) {
                value = v.derivative.type;
            } else if (v.derivative.type == null || value.betterThan(v.derivative.type)) {
                v.derivative.type = value;
                changed = true;
            }
        }
        if (value == null) {
            value = v.reference.variable.type;
        } else if (v.reference.variable.type == null || value.betterThan(v.reference.variable.type)) {
            v.reference.variable.type = value;
            changed = true;
        }
        if (v != v.reference.variable && value != null && value.betterThan(v.type)) {
            v.type = value;
            changed = true;
        }
    }
    for (EquationSet s : parts) {
        if (s.determineTypesEval())
            changed = true;
    }
    return changed;
}
Also used : Type(gov.sandia.n2a.language.Type) AccessVariable(gov.sandia.n2a.language.AccessVariable) Instance(gov.sandia.n2a.language.type.Instance) EvaluationException(gov.sandia.n2a.language.EvaluationException) UnsupportedFunctionException(gov.sandia.n2a.language.UnsupportedFunctionException) ParseException(gov.sandia.n2a.language.ParseException)

Example 12 with Instance

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

the class EquationSet method findConstantsEval.

protected boolean findConstantsEval() {
    boolean changed = false;
    for (Variable v : variables) {
        if (v.simplify())
            changed = true;
        // "externalWrite" -- Regardless of the local math, a variable that gets written is not constant.
        if (v.hasAny("constant", "initOnly", "externalWrite"))
            continue;
        if (// A variable with a derivative is usually not constant, with the following exceptions ...
        v.derivative != null) {
            // 1) Check for unconditional constant.
            if (v.equations.size() == 1) {
                EquationEntry e = v.equations.first();
                if (// Must be unconditional. No exception for $init. (Non-integrated variables do get an exception for $init; see below.)
                e.expression instanceof Constant && e.condition == null) {
                    changed = true;
                    v.addAttribute("constant");
                    v.removeDependencyOn(v.derivative);
                    v.derivative = null;
                    continue;
                }
            }
            // 2a) Check for pure circular dependency.
            Variable top = v;
            while (// This single dependency must be the derivative.
            top.uses != null && top.uses.size() == 1) {
                if (top.derivative != null) {
                    top = top.derivative;
                    continue;
                }
                // Its single dependency is not a derivative, but could be anything else.
                if (// This is a pure circular dependency.
                top.uses.containsKey(v)) {
                    // Evaluate top. Initial value of v must be zero, because otherwise it would depend on other variables or be trapped above as an unconditional constant.
                    // We can only make this assumption here.
                    Instance instance = new Instance() {

                        public Scalar zero = new Scalar(0);

                        // all AccessVariable objects will reach here first.
                        public Type get(VariableReference r) throws EvaluationException {
                            return zero;
                        }
                    };
                    Type result = top.eval(instance);
                    if (result instanceof Scalar && ((Scalar) result).value == 0) {
                        changed = true;
                        top.addAttribute("constant");
                        // Should just be v, but there may be multiple references.
                        top.removeDependencies();
                        top.equations.clear();
                        EquationEntry e = new EquationEntry(top, "");
                        e.expression = new Constant(0);
                        top.add(e);
                    }
                }
                // And fall through to case 2. If top is immediately v.derivative, then it will be detached in this iteration.
                break;
            }
            // 2) Check if derivative is constant zero.
            if (!v.derivative.hasAttribute("constant"))
                continue;
            EquationEntry e = v.derivative.equations.first();
            if (!((Constant) e.expression).value.isZero())
                continue;
            changed = true;
            v.removeDependencyOn(v.derivative);
            v.derivative = null;
            if (v.equations.isEmpty()) {
                // $t, $t', $index an $type are also added without equations.
                if (v.name.equals("$t") && v.order < 2)
                    continue;
                v.addAttribute("constant");
                e = new EquationEntry(v, "");
                e.expression = new Constant(0);
                v.add(e);
                // Already determined that v is constant, so done with it.
                continue;
            }
        // v is now effectively an ordinary variable (no derivative) with equation(s), so fall through ...
        }
        if (v.equations.size() != 1) {
            if (// Special cases for $variables
            v.equations.isEmpty()) {
                if (v.name.equals("$index")) {
                    // Check if $n has become constant 1, that is, if we have detected a singleton in later processing.
                    // In this case, $index should become constant 0.
                    Variable n = find(new Variable("$n"));
                    if (n != null && n.hasAttribute("constant")) {
                        if (n.equations.first().expression.getDouble() == 1) {
                            changed = true;
                            v.removeAttribute("initOnly");
                            v.addAttribute("constant");
                            v.unit = AbstractUnit.ONE;
                            v.equations = new TreeSet<EquationEntry>();
                            EquationEntry e = new EquationEntry(v, "");
                            e.expression = new Constant(0);
                            e.expression.unit = AbstractUnit.ONE;
                            v.add(e);
                        }
                    }
                } else if (// $t'
                v.name.equals("$t") && v.order == 1 && container != null) {
                    // Copy constant $t' from container.
                    Variable parentDt = container.find(v);
                    if (parentDt.hasAttribute("constant")) {
                        changed = true;
                        v.addAttribute("constant");
                        EquationEntry e = new EquationEntry(v, "");
                        v.add(e);
                        EquationEntry parentE = parentDt.equations.first();
                        e.expression = new Constant(parentE.expression.getDouble());
                        e.expression.unit = AbstractUnit.ONE;
                    }
                }
            }
            continue;
        }
        // At this point, the variable satisfies most of the requirements to be constant.
        // It has no external writers or derivatives, so only its single equation can change it.
        // The remaining question is whether the equation is an unconditional constant.
        EquationEntry e = v.equations.first();
        // Notice that a constant equation conditioned on $init is effectively unconditional.
        if (e.condition != null && !e.ifString.equals("$init"))
            continue;
        if (e.expression instanceof Constant) {
            changed = true;
            v.addAttribute("constant");
            // in case it was $init
            e.condition = null;
            e.ifString = "";
        }
    }
    for (EquationSet s : parts) {
        if (s.findConstantsEval())
            changed = true;
    }
    return changed;
}
Also used : Type(gov.sandia.n2a.language.Type) AccessVariable(gov.sandia.n2a.language.AccessVariable) Instance(gov.sandia.n2a.language.type.Instance) Constant(gov.sandia.n2a.language.Constant) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 13 with Instance

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

the class Population method finish.

public boolean finish(Simulator simulator) {
    InternalBackendData bed = (InternalBackendData) equations.backendData;
    // Capture $n before finalize, so we can compare it for changes.
    double oldN = 0;
    if (bed.populationCanResize)
        oldN = ((Scalar) get(bed.n)).value;
    // Finalize
    for (Variable v : bed.globalBufferedExternal) setFinal(v, getFinal(v));
    clearExternalWriteBuffers(bed.globalBufferedExternalWrite);
    // Structural dynamics
    if (bed.populationCanResize) {
        // This is the finalized value of $n.
        int newN = Math.max(0, (int) ((Scalar) get(bed.n)).value);
        if (// $n shares control with other specials, so coordinate them.
        bed.populationCanGrowOrDie) {
            if (bed.n.derivative == null) {
                if (// $n was explicitly changed, so its value takes precedence
                newN != oldN)
                    // $n was explicitly changed, so its value takes precedence
                    simulator.resize(this, (int) newN);
                else
                    // -1 means to update $n from this.n. This can only be done after other parts are finalized, as they may impose structural dynamics via $p or $type.
                    simulator.resize(this, -1);
            } else // the rate of change in $n is pre-determined, so it relentlessly overrides any other structural dynamics
            {
                simulator.resize(this, newN);
            }
        } else // $n is the only kind of structural dynamics, so only do a resize() when needed
        {
            if (newN != n)
                simulator.resize(this, newN);
        }
    }
    if (equations.connectionBindings != null) {
        // Check poll deadline.
        boolean shouldConnect = false;
        if (bed.poll >= 0) {
            double pollDeadline = valuesFloat[bed.pollDeadline];
            double t = simulator.currentEvent.t;
            if (t >= pollDeadline)
                shouldConnect = true;
        }
        // To limit work, only do this for shallow structures that don't require enumerating sub-populations.
        if (!shouldConnect) {
            for (ConnectionBinding target : equations.connectionBindings) {
                InternalBackendData cbed = (InternalBackendData) target.endpoint.backendData;
                if (cbed.singleton)
                    continue;
                // Resolve binding
                Instance current = this;
                for (Object o : target.resolution) {
                    Resolver r = (Resolver) o;
                    if (r.shouldEnumerate(current))
                        break;
                    current = r.resolve(current);
                }
                if (current.equations != target.endpoint)
                    continue;
                int firstborn = (int) current.valuesFloat[cbed.firstborn];
                @SuppressWarnings("unchecked") int size = (int) ((List<Part>) current.valuesObject[cbed.instances]).size();
                if (firstborn < size) {
                    shouldConnect = true;
                    break;
                }
            }
        }
        if (shouldConnect)
            simulator.connect(this);
    }
    return true;
}
Also used : Variable(gov.sandia.n2a.eqset.Variable) Instance(gov.sandia.n2a.language.type.Instance) ConnectionBinding(gov.sandia.n2a.eqset.EquationSet.ConnectionBinding) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 14 with Instance

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

the class SymbolStateVar1 method getDefinition.

@Override
public String getDefinition(XyceRenderer renderer) {
    String translatedEq = renderer.change(eq.expression);
    Variable v = eq.variable;
    VariableReference r = v.reference;
    if (// symbol is defined here; no += allowed within same part
    r.index < 0) {
        return Xyceisms.defineDiffEq(v.name, renderer.pi.hashCode(), translatedEq);
    }
    // This symbol refers to a symbol in another part. We don't re-define the
    // variable, rather we create another diff eq that updates the existing one.
    Instance target = (Instance) renderer.pi.valuesObject[r.index];
    String thisVarname = r.variable.name + "_" + target.hashCode();
    String eqName = v.name + "_" + renderer.pi.hashCode();
    return Xyceisms.updateDiffEq(eqName, thisVarname, translatedEq);
}
Also used : Variable(gov.sandia.n2a.eqset.Variable) VariableReference(gov.sandia.n2a.eqset.VariableReference) Instance(gov.sandia.n2a.language.type.Instance)

Example 15 with Instance

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

the class EventSpikeMulti method run.

public void run(Simulator simulator) {
    setFlag();
    for (Instance i : targets) simulator.integrate(i);
    for (Instance i : targets) i.update(simulator);
    for (Instance i : targets) {
        boolean live = i.finish(simulator);
        InternalBackendData bed = (InternalBackendData) i.equations.backendData;
        for (Variable v : bed.eventReferences) ((Instance) i.valuesObject[v.reference.index]).finishEvent(v.reference.variable);
        if (!live)
            i.dequeue();
    }
}
Also used : Variable(gov.sandia.n2a.eqset.Variable) Instance(gov.sandia.n2a.language.type.Instance)

Aggregations

Instance (gov.sandia.n2a.language.type.Instance)17 Scalar (gov.sandia.n2a.language.type.Scalar)10 AccessVariable (gov.sandia.n2a.language.AccessVariable)8 Type (gov.sandia.n2a.language.Type)8 Variable (gov.sandia.n2a.eqset.Variable)7 Operator (gov.sandia.n2a.language.Operator)7 ArrayList (java.util.ArrayList)5 Visitor (gov.sandia.n2a.language.Visitor)4 InstanceTemporaries (gov.sandia.n2a.backend.internal.InstanceTemporaries)3 EventSource (gov.sandia.n2a.backend.internal.InternalBackendData.EventSource)3 EventTarget (gov.sandia.n2a.backend.internal.InternalBackendData.EventTarget)3 VariableReference (gov.sandia.n2a.eqset.VariableReference)3 Constant (gov.sandia.n2a.language.Constant)3 Population (gov.sandia.n2a.backend.internal.Population)2 Symbol (gov.sandia.n2a.backend.xyce.netlist.Symbol)2 XyceRenderer (gov.sandia.n2a.backend.xyce.netlist.XyceRenderer)2 EquationEntry (gov.sandia.n2a.eqset.EquationEntry)2 EquationSet (gov.sandia.n2a.eqset.EquationSet)2 EvaluationException (gov.sandia.n2a.language.EvaluationException)2 Output (gov.sandia.n2a.language.function.Output)2