Search in sources :

Example 41 with ExpressionException

use of cbit.vcell.parser.ExpressionException in project vcell by virtualcell.

the class MassActionSolver method reconstructedRate.

private static Expression reconstructedRate(Expression forwardExp, Expression reverseExp, ArrayList<ReactionParticipant> reactants, ArrayList<ReactionParticipant> products, NameScope ns) throws ExpressionException {
    Expression result = null;
    Expression reactExpr = null;
    Expression prodExpr = null;
    if (forwardExp != null) {
        reactExpr = new Expression(forwardExp);
        // loop through reactants
        for (ReactionParticipant reactant : reactants) {
            reactExpr = Expression.mult(reactExpr, Expression.power(new Expression(reactant.getSpeciesContext(), ns), new Expression(reactant.getStoichiometry())));
        }
    }
    if (reverseExp != null) {
        prodExpr = new Expression(reverseExp);
        // loop through products
        for (ReactionParticipant product : products) {
            prodExpr = Expression.mult(prodExpr, Expression.power(new Expression(product.getSpeciesContext(), ns), new Expression(product.getStoichiometry())));
        }
    }
    if (reactExpr == null && prodExpr != null) {
        result = Expression.negate(prodExpr);
    } else if (reactExpr != null && prodExpr == null) {
        result = reactExpr;
    } else if (reactExpr != null && prodExpr != null) {
        result = Expression.add(reactExpr, Expression.negate(prodExpr));
    } else {
        throw new ExpressionException("Both forward and reverse rate constants are null.");
    }
    return result.flatten();
}
Also used : Expression(cbit.vcell.parser.Expression) ExpressionException(cbit.vcell.parser.ExpressionException)

Example 42 with ExpressionException

use of cbit.vcell.parser.ExpressionException in project vcell by virtualcell.

the class MassActionSolver method solveMassAction.

public static MassActionFunction solveMassAction(Parameter optionalForwardRateParameter, Parameter optionalReverseRateParameter, Expression orgExp, ReactionStep rs) throws ExpressionException, ModelException, DivideByZeroException {
    MassActionFunction maFunc = new MassActionFunction();
    // get reactants, products, overlaps, non-overlap reactants and non-overlap products
    ArrayList<ReactionParticipant> reactants = new ArrayList<ReactionParticipant>();
    ArrayList<ReactionParticipant> products = new ArrayList<ReactionParticipant>();
    ReactionParticipant[] rp = rs.getReactionParticipants();
    // should use this one to compare functional equavalent since this duplicatedExp has all params substituted.
    Expression duplicatedExp = substituteParameters(orgExp, false);
    // separate the reactants and products, fluxes, catalysts
    String rxnName = rs.getName();
    // reaction with membrane current can not be transformed to mass action
    if (rs.getPhysicsOptions() == ReactionStep.PHYSICS_MOLECULAR_AND_ELECTRICAL || rs.getPhysicsOptions() == ReactionStep.PHYSICS_ELECTRICAL_ONLY) {
        throw new ModelException("Kinetics of reaction " + rxnName + " has membrane current. It can not be automatically transformed to Mass Action kinetics.");
    }
    for (int i = 0; i < rp.length; i++) {
        if (rp[i] instanceof Reactant) {
            reactants.add(rp[i]);
        } else if (rp[i] instanceof Product) {
            products.add(rp[i]);
        } else if (rp[i] instanceof Catalyst) {
            String catalystName = rp[i].getSpeciesContext().getName();
            // only if duplictedExp is not a non-linear function of catalystName.
            if (duplicatedExp.hasSymbol(catalystName)) {
                // Only when catalyst appears in ReactionRate, we add catalyst to both reactant and product
                // the stoichiometry should be set to 1.
                ReactionParticipant catalystRP = new ReactionParticipant(null, rs, rp[i].getSpeciesContext(), 1) {

                    public boolean compareEqual(Matchable obj) {
                        ReactionParticipant rp = (ReactionParticipant) obj;
                        if (rp == null) {
                            return false;
                        }
                        if (!Compare.isEqual(getSpecies(), rp.getSpecies())) {
                            return false;
                        }
                        if (!Compare.isEqual(getStructure(), rp.getStructure())) {
                            return false;
                        }
                        if (getStoichiometry() != rp.getStoichiometry()) {
                            return false;
                        }
                        return true;
                    }

                    @Override
                    public void writeTokens(PrintWriter pw) {
                    }

                    @Override
                    public void fromTokens(CommentStringTokenizer tokens, Model model) throws Exception {
                    }
                };
                products.add(catalystRP);
                reactants.add(catalystRP);
            }
        }
    }
    /**
     * The code below is going to solve reaction with kinetics that are NOT Massaction. Or Massaction with catalysts involved.
     */
    // 
    // 2x2 rational matrix
    // 
    // lets define
    // J() is the substituted total rate expression
    // P() as the theoretical "product" term with Kf = 1
    // R() as the theoretical "reactant" term with Kr = 1
    // 
    // Kf * R([1 1 1])  - Kr * P([1 1 1])  = J([1 1 1])
    // Kf * R([2 3 4])  - Kr * P([2 3 4])  = J([2 3 4])
    // 
    // in matrix form,
    // 
    // |                                        |
    // | R([1 1 1])   -P([1 1 1])    J([1 1 1]) |
    // | R([2 3 4])   -P([2 3 4])    J([2 3 4]) |
    // |                                        |
    // 
    // 
    // example: Kf*A*B^2*C - Kr*C*A
    // J() = forwardRate*43/Kabc*A*B^2*C - (myC*5-2)*C*A
    // P() = C*A
    // R() = A*B^2*C
    // 
    // |                                              |
    // | R([1 1 1])  -P([1 1 1])    J([1 1 1])        |
    // | R([2 3 4])  -P([2 3 4])    J([2 3 4])        |
    // |                                              |
    // 
    // |                                                                              |
    // | R([1 1 1])*R([2 3 4])    -P([1 1 1])*R([2 3 4])     J([1 1 1])*R([2 3 4])    |
    // | R([2 3 4])*R([1 1 1])    -P([2 3 4])*R([1 1 1])     J([2 3 4])*R([1 1 1])    |
    // |                                                                              |
    // 
    // 
    // |                                                                                                                    |
    // | R([1 1 1])*R([2 3 4])  -P([1 1 1])*R([2 3 4])                         J([1 1 1])*R([2 3 4])                        |
    // | 0                      -P([2 3 4])*R([1 1 1])+P([1 1 1])*R([2 3 4])   J([2 3 4])*R([1 1 1])-J([1 1 1])*R([2 3 4])  |
    // |                                                                                                                    |
    // 
    // 
    // 
    // 
    Expression forwardExp = null;
    Expression reverseExp = null;
    Expression R_exp = new Expression(1);
    if (reactants.size() > 0) {
        R_exp = new Expression(1.0);
        for (ReactionParticipant reactant : reactants) {
            R_exp = Expression.mult(R_exp, Expression.power(new Expression(reactant.getName()), new Expression(reactant.getStoichiometry())));
        }
    }
    Expression P_exp = new Expression(1);
    if (products.size() > 0) {
        P_exp = new Expression(1.0);
        for (ReactionParticipant product : products) {
            P_exp = Expression.mult(P_exp, Expression.power(new Expression(product.getName()), new Expression(product.getStoichiometry())));
        }
    }
    HashSet<String> reactionParticipantNames = new HashSet<String>();
    for (ReactionParticipant reactionParticipant : rs.getReactionParticipants()) {
        reactionParticipantNames.add(reactionParticipant.getName());
    }
    Expression R_1 = new Expression(R_exp);
    Expression R_2 = new Expression(R_exp);
    Expression P_1 = new Expression(P_exp);
    Expression P_2 = new Expression(P_exp);
    Expression J_1 = new Expression(duplicatedExp);
    Expression J_2 = new Expression(duplicatedExp);
    int index = 0;
    for (String rpName : reactionParticipantNames) {
        R_1.substituteInPlace(new Expression(rpName), new Expression(1.0));
        R_2.substituteInPlace(new Expression(rpName), new Expression(primeIntNumbers[index]));
        P_1.substituteInPlace(new Expression(rpName), new Expression(1.0));
        P_2.substituteInPlace(new Expression(rpName), new Expression(primeIntNumbers[index]));
        J_1.substituteInPlace(new Expression(rpName), new Expression(1.0));
        J_2.substituteInPlace(new Expression(rpName), new Expression(primeIntNumbers[index]));
        index++;
    }
    R_1 = R_1.flatten();
    R_2 = R_2.flatten();
    P_1 = P_1.flatten();
    P_2 = P_2.flatten();
    J_1 = J_1.flatten();
    J_2 = J_2.flatten();
    // e.g. A+B <-> A+B, A+2B <-> A+2B
    if (ExpressionUtils.functionallyEquivalent(R_exp, P_exp, false, 1e-8, 1e-8)) {
        throw new ModelException(VCellErrorMessages.getMassActionSolverMessage(rs.getName(), "Identical reactants and products not supported for stochastic models."));
    }
    if (R_exp.compareEqual(new Expression(1)) && P_exp.compareEqual(new Expression(1))) {
        // no reactants, no products ... nothing to do
        forwardExp = null;
        reverseExp = null;
    } else {
        // both reactants and products
        RationalExpMatrix matrix = new RationalExpMatrix(2, 3);
        matrix.set_elem(0, 0, RationalExpUtils.getRationalExp(R_1, true));
        matrix.set_elem(0, 1, RationalExpUtils.getRationalExp(Expression.negate(P_1), true));
        matrix.set_elem(0, 2, RationalExpUtils.getRationalExp(J_1, true));
        matrix.set_elem(1, 0, RationalExpUtils.getRationalExp(R_2, true));
        matrix.set_elem(1, 1, RationalExpUtils.getRationalExp(Expression.negate(P_2), true));
        matrix.set_elem(1, 2, RationalExpUtils.getRationalExp(J_2, true));
        RationalExp[] solution;
        try {
            // matrix.show();
            solution = matrix.solveLinearExpressions();
            // solution[0] is forward rate.
            solution[0] = solution[0].simplify();
            // solution[1] is reverse rate.
            solution[1] = solution[1].simplify();
        } catch (MatrixException e) {
            e.printStackTrace();
            throw new ModelException(VCellErrorMessages.getMassActionSolverMessage(rs.getName(), "MatrixException: " + e.getMessage()));
        }
        forwardExp = new Expression(solution[0].infixString());
        reverseExp = new Expression(solution[1].infixString());
        // for massAction, if there is no reactant in the forward rate, the forwardExp should be set to null to avoid writing jump process for the forward reaction.
        if (R_exp.compareEqual(new Expression(1)) && rs.getKinetics().getKineticsDescription().equals(KineticsDescription.MassAction)) {
            forwardExp = null;
        }
        // for massAction, if there is no product in the reverse rate, the reverseExp should be set to null to avoid writing jump process for the reverse reaction.
        if (P_exp.compareEqual(new Expression(1)) && rs.getKinetics().getKineticsDescription().equals(KineticsDescription.MassAction)) {
            reverseExp = null;
        }
    }
    if (forwardExp != null) {
        forwardExp.bindExpression(rs);
    }
    if (reverseExp != null) {
        reverseExp.bindExpression(rs);
    }
    // Reconstruct the rate based on the extracted forward rate and reverse rate. If the reconstructed rate is not equivalent to the original rate,
    // it means the original rate is not in the form of Kf*r1^n1*r2^n2-Kr*p1^m1*p2^m2.
    Expression constructedExp = reconstructedRate(forwardExp, reverseExp, reactants, products, rs.getNameScope());
    Expression orgExp_withoutCatalyst = removeCatalystFromExp(duplicatedExp, rs);
    Expression constructedExp_withoutCatalyst = removeCatalystFromExp(constructedExp, rs);
    if (!ExpressionUtils.functionallyEquivalent(orgExp_withoutCatalyst, constructedExp_withoutCatalyst, false, 1e-8, 1e-8)) {
        throw new ModelException(VCellErrorMessages.getMassActionSolverMessage(rs.getName(), "Mathmatical form incompatible with mass action."));
    }
    // check if forward rate constant and reverse rate constant both can be evaluated to constants(numbers) after substituting all parameters.
    if (forwardExp != null) {
        Expression forwardExpCopy = new Expression(forwardExp);
        try {
            substituteParameters(forwardExpCopy, true).evaluateConstant();
        } catch (ExpressionException e) {
            throw new ModelException(VCellErrorMessages.getMassActionSolverMessage(rs.getName(), "Problem in forward rate '" + forwardExp.infix() + "', " + e.getMessage()));
        }
        // 
        if (optionalForwardRateParameter != null) {
            Expression forwardRateParameterCopy = new Expression(optionalForwardRateParameter, optionalForwardRateParameter.getNameScope());
            try {
                substituteParameters(forwardRateParameterCopy, true).evaluateConstant();
                if (forwardExpCopy.compareEqual(forwardRateParameterCopy)) {
                    forwardExp = new Expression(optionalForwardRateParameter, optionalForwardRateParameter.getNameScope());
                }
            } catch (ExpressionException e) {
                // not expecting a problem because forwardExpCopy didn't have a problem, but in any case it is ok to swallow this exception
                e.printStackTrace(System.out);
            }
        }
    }
    if (reverseExp != null) {
        Expression reverseExpCopy = new Expression(reverseExp);
        try {
            substituteParameters(reverseExpCopy, true).evaluateConstant();
        } catch (ExpressionException e) {
            throw new ModelException(VCellErrorMessages.getMassActionSolverMessage(rs.getName(), "Problem in reverse rate '" + reverseExp.infix() + "', " + e.getMessage()));
        }
        // 
        if (optionalReverseRateParameter != null) {
            Expression reverseRateParameterCopy = new Expression(optionalReverseRateParameter, optionalReverseRateParameter.getNameScope());
            try {
                substituteParameters(reverseRateParameterCopy, true).evaluateConstant();
                if (reverseExpCopy.compareEqual(reverseRateParameterCopy)) {
                    reverseExp = new Expression(optionalReverseRateParameter, optionalReverseRateParameter.getNameScope());
                }
            } catch (ExpressionException e) {
                // not expecting a problem because reverseExpCopy didn't have a problem, but in any case it is ok to swallow this exception
                e.printStackTrace(System.out);
            }
        }
    }
    maFunc.setForwardRate(forwardExp);
    maFunc.setReverseRate(reverseExp);
    maFunc.setReactants(reactants);
    maFunc.setProducts(products);
    return maFunc;
}
Also used : ArrayList(java.util.ArrayList) RationalExp(cbit.vcell.matrix.RationalExp) Matchable(org.vcell.util.Matchable) ExpressionException(cbit.vcell.parser.ExpressionException) MatrixException(cbit.vcell.matrix.MatrixException) Expression(cbit.vcell.parser.Expression) RationalExpMatrix(cbit.vcell.matrix.RationalExpMatrix) CommentStringTokenizer(org.vcell.util.CommentStringTokenizer) PrintWriter(java.io.PrintWriter) HashSet(java.util.HashSet)

Example 43 with ExpressionException

use of cbit.vcell.parser.ExpressionException in project vcell by virtualcell.

the class Model method gatherIssues.

/**
 * Insert the method's description here.
 * Creation date: (5/12/2004 10:38:12 PM)
 * @param issueList java.util.Vector
 */
public void gatherIssues(IssueContext issueContext, List<Issue> issueList) {
    issueContext = issueContext.newChildContext(ContextType.Model, this);
    // 
    try {
        for (ModelParameter modelParameter : fieldModelParameters) {
            Expression exp = modelParameter.getExpression();
            String[] symbols = exp.getSymbols();
            if (symbols != null) {
                String issueMsgPrefix = "Global parameter '" + modelParameter.getName() + "' ";
                for (int j = 0; j < symbols.length; j++) {
                    SymbolTableEntry ste = exp.getSymbolBinding(symbols[j]);
                    if (ste == null) {
                        issueList.add(new Issue(modelParameter, issueContext, IssueCategory.ModelParameterExpressionError, issueMsgPrefix + "references undefined symbol '" + symbols[j] + "'", Issue.SEVERITY_ERROR));
                    } else if (ste instanceof SpeciesContext) {
                        if (!contains((SpeciesContext) ste)) {
                            issueList.add(new Issue(modelParameter, issueContext, IssueCategory.ModelParameterExpressionError, issueMsgPrefix + "references undefined species '" + symbols[j] + "'", Issue.SEVERITY_ERROR));
                        }
                    } else if (ste instanceof ModelParameter) {
                        if (!contains((ModelParameter) ste)) {
                            issueList.add(new Issue(modelParameter, issueContext, IssueCategory.ModelParameterExpressionError, issueMsgPrefix + "references undefined global parameter '" + symbols[j] + "'", Issue.SEVERITY_ERROR));
                        }
                    }
                }
            }
        }
        // 
        for (int i = 0; i < fieldModelParameters.length; i++) {
            try {
                VCUnitEvaluator unitEvaluator = new VCUnitEvaluator(getUnitSystem());
                VCUnitDefinition paramUnitDef = fieldModelParameters[i].getUnitDefinition();
                VCUnitDefinition expUnitDef = unitEvaluator.getUnitDefinition(fieldModelParameters[i].getExpression());
                if (paramUnitDef == null) {
                    issueList.add(new Issue(fieldModelParameters[i], issueContext, IssueCategory.Units, "defined unit is null", Issue.SEVERITY_WARNING));
                } else if (expUnitDef == null) {
                    issueList.add(new Issue(fieldModelParameters[i], issueContext, IssueCategory.Units, "computed unit is null", Issue.SEVERITY_WARNING));
                } else if (paramUnitDef.isTBD()) {
                    issueList.add(new Issue(fieldModelParameters[i], issueContext, IssueCategory.Units, "unit is undefined (" + unitSystem.getInstance_TBD().getSymbol() + ")", Issue.SEVERITY_WARNING));
                } else if (!paramUnitDef.isEquivalent(expUnitDef) && !expUnitDef.isTBD()) {
                    issueList.add(new Issue(fieldModelParameters[i], issueContext, IssueCategory.Units, "unit mismatch, computed = [" + expUnitDef.getSymbol() + "]", Issue.SEVERITY_WARNING));
                }
            } catch (VCUnitException e) {
                issueList.add(new Issue(fieldModelParameters[i], issueContext, IssueCategory.Units, "units inconsistent: " + e.getMessage(), Issue.SEVERITY_WARNING));
            } catch (ExpressionException e) {
                issueList.add(new Issue(fieldModelParameters[i], issueContext, IssueCategory.Units, "units inconsistent: " + e.getMessage(), Issue.SEVERITY_WARNING));
            }
        }
    } catch (Throwable e) {
        e.printStackTrace(System.out);
        issueList.add(new Issue(this, issueContext, IssueCategory.Units, "unexpected exception: " + e.getMessage(), Issue.SEVERITY_WARNING));
    }
    // 
    for (Structure struct : fieldStructures) {
        struct.gatherIssues(issueContext, issueList);
    }
    // 
    for (int i = 0; i < fieldReactionSteps.length; i++) {
        fieldReactionSteps[i].gatherIssues(issueContext, issueList);
    }
    // 
    // get issues from species contexts (species patterns)
    // 
    int seedSpeciesCount = 0;
    for (int i = 0; i < fieldSpeciesContexts.length; i++) {
        if (fieldSpeciesContexts[i].hasSpeciesPattern()) {
            seedSpeciesCount++;
        }
        fieldSpeciesContexts[i].gatherIssues(issueContext, issueList);
    }
    if (seedSpeciesCount == 0 && !rbmModelContainer.getReactionRuleList().isEmpty()) {
        String msg = "At least one seed species is required.";
        issueList.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, Issue.Severity.WARNING));
    }
    // 
    // get issues for symbol name clashes (specifically structures with same voltage names or structure names)
    // 
    HashSet<SymbolTableEntry> steHashSet = new HashSet<SymbolTableEntry>();
    gatherLocalEntries(steHashSet);
    Iterator<SymbolTableEntry> iter = steHashSet.iterator();
    Hashtable<String, SymbolTableEntry> symbolHashtable = new Hashtable<String, SymbolTableEntry>();
    while (iter.hasNext()) {
        SymbolTableEntry ste = iter.next();
        SymbolTableEntry existingSTE = symbolHashtable.get(ste.getName());
        if (existingSTE != null) {
            issueList.add(new Issue(this, issueContext, IssueCategory.Identifiers, "model symbol \"" + ste.getName() + "\" is used within \"" + ste.getNameScope().getName() + "\" and \"" + existingSTE.getNameScope().getName() + "\"", Issue.SEVERITY_ERROR));
        } else {
            symbolHashtable.put(ste.getName(), ste);
        }
    }
    // 
    // gather issues for electrical topology (unspecified +ve or -ve features, or +ve feature == -ve feature
    // 
    getElectricalTopology().gatherIssues(issueContext, issueList);
    // 
    if (rbmModelContainer == null) {
        issueList.add(new Issue(this, issueContext, IssueCategory.InternalError, "Rbm Model Container is null", Issue.SEVERITY_WARNING));
    } else {
        rbmModelContainer.gatherIssues(issueContext, issueList);
    }
}
Also used : Issue(org.vcell.util.Issue) Hashtable(java.util.Hashtable) ExpressionException(cbit.vcell.parser.ExpressionException) VCUnitException(cbit.vcell.units.VCUnitException) VCUnitEvaluator(cbit.vcell.parser.VCUnitEvaluator) SymbolTableEntry(cbit.vcell.parser.SymbolTableEntry) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) Expression(cbit.vcell.parser.Expression) HashSet(java.util.HashSet)

Example 44 with ExpressionException

use of cbit.vcell.parser.ExpressionException in project vcell by virtualcell.

the class MathDescription method gatherIssues.

/**
 * This method was created in VisualAge.
 * @return boolean
 */
public void gatherIssues(IssueContext issueContext, List<Issue> issueList) {
    issueContext = issueContext.newChildContext(ContextType.MathDescription, this);
    setWarning(null);
    if (geometry == null) {
        Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_NoGeometry, VCellErrorMessages.MATH_DESCRIPTION_GEOMETRY_1, Issue.SEVERITY_ERROR);
        issueList.add(issue);
    }
    if (isSpatialStoch() && geometry.getDimension() != 3) {
        Issue issue = new Issue(geometry, issueContext, IssueCategory.Smoldyn_Geometry_3DWarning, "VCell spatial stochastic models only support 3D geometry.", Issue.SEVERITY_ERROR);
        issueList.add(issue);
    }
    // check Constant are really constants
    for (int i = 0; i < variableList.size(); i++) {
        Variable var = variableList.get(i);
        if (var instanceof Constant) {
            try {
                ((Constant) var).getExpression().evaluateConstant();
            } catch (Exception ex) {
                ex.printStackTrace(System.out);
                Issue issue = new Issue(var, issueContext, IssueCategory.MathDescription_Constant_NotANumber, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_CONSTANT, var.getExpression().infix()), Issue.SEVERITY_ERROR);
                issueList.add(issue);
            }
        }
    }
    // 
    // count number of variables of each type
    // 
    int volVarCount = 0;
    int memVarCount = 0;
    int filVarCount = 0;
    int volRegionVarCount = 0;
    int memRegionVarCount = 0;
    int filRegionVarCount = 0;
    int stochVarCount = 0;
    int pointVarCount = 0;
    for (int i = 0; i < variableList.size(); i++) {
        Variable var = variableList.get(i);
        if (var instanceof VolVariable) {
            volVarCount++;
        } else if (var instanceof MemVariable) {
            memVarCount++;
        } else if (var instanceof FilamentVariable) {
            filVarCount++;
        } else if (var instanceof VolumeRegionVariable) {
            volRegionVarCount++;
        } else if (var instanceof MembraneRegionVariable) {
            memRegionVarCount++;
        } else if (var instanceof FilamentRegionVariable) {
            filRegionVarCount++;
        } else if (var instanceof StochVolVariable) {
            stochVarCount++;
        } else if (var instanceof PointVariable) {
            pointVarCount++;
        }
    }
    // 
    for (int i = 0; i < subDomainList.size(); i++) {
        try {
            SubDomain subDomain = subDomainList.get(i);
            Enumeration<Equation> equEnum = subDomain.getEquations();
            while (equEnum.hasMoreElements()) {
                Equation equ = equEnum.nextElement();
                equ.checkValid(this, subDomain);
                equ.bind(this);
            }
            FastSystem fastSystem = subDomain.getFastSystem();
            if (fastSystem != null) {
                Enumeration<FastRate> frEnum = fastSystem.getFastRates();
                while (frEnum.hasMoreElements()) {
                    FastRate fr = frEnum.nextElement();
                    fr.bind(this);
                }
                Enumeration<FastInvariant> fiEnum = fastSystem.getFastInvariants();
                while (fiEnum.hasMoreElements()) {
                    FastInvariant fi = fiEnum.nextElement();
                    fi.bind(this);
                }
            }
            for (ParticleProperties pp : subDomain.getParticleProperties()) {
                pp.bind(this);
            }
            for (ParticleJumpProcess pjp : subDomain.getParticleJumpProcesses()) {
                pjp.bind(this);
                Expression rateDefinition = null;
                JumpProcessRateDefinition jprd = pjp.getParticleRateDefinition();
                if (jprd instanceof MacroscopicRateConstant) {
                    rateDefinition = MathUtilities.substituteFunctions(((MacroscopicRateConstant) jprd).getExpression(), this);
                } else if (jprd instanceof InteractionRadius) {
                    rateDefinition = MathUtilities.substituteFunctions(((InteractionRadius) jprd).getExpression(), this);
                } else {
                    new RuntimeException("The jump process rate definition is not supported");
                }
                String[] symbols = rateDefinition.getSymbols();
                if (symbols != null) {
                    for (String symbol : symbols) {
                        // throw exception for particle variables, particle variable cannot be referenced
                        Variable var = getVariable(symbol);
                        if (var instanceof ParticleVariable) {
                            throw new MathException("Stochastic variables can not be referenced in functions and equations.");
                        }
                        if (subDomain instanceof CompartmentSubDomain) {
                            if ((var instanceof MembraneRegionVariable || var instanceof MemVariable)) {
                                throw new MathException("Volume reaction: " + pjp.getName() + " cannot reference membrane variable: " + var.getName() + ".");
                            }
                        }
                    }
                }
            }
        } catch (ExpressionBindingException e) {
            Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_ExpressionBindingException, e.getMessage(), Issue.SEVERITY_ERROR);
            issueList.add(issue);
        } catch (ExpressionException e) {
            Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_ExpressionException, e.getMessage(), Issue.SEVERITY_ERROR);
            issueList.add(issue);
        } catch (MathException e) {
            Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_MathException, e.getMessage(), Issue.SEVERITY_ERROR);
            issueList.add(issue);
        }
    }
    // 
    if (geometry.getDimension() == 0) {
        // 
        if (subDomainList.size() != 1) {
            Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_CompartmentalModel, VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_MODEL_1, Issue.SEVERITY_ERROR);
            issueList.add(issue);
        } else if (subDomainList.size() == 1) {
            if (!(subDomainList.get(0) instanceof CompartmentSubDomain)) {
                Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_CompartmentalModel, VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_MODEL_2, Issue.SEVERITY_ERROR);
                issueList.add(issue);
            }
            CompartmentSubDomain subDomain = (CompartmentSubDomain) subDomainList.get(0);
            // distinguish ODE model and stochastic model
            if (isNonSpatialStoch()) {
                if (stochVarCount == 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_StochasticModel, VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_STOCHASTIC_MODEL_1, Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (subDomain.getJumpProcesses().size() == 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_StochasticModel, VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_STOCHASTIC_MODEL_2, Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                // check variable initial condition
                for (VarIniCondition varIniCondition : subDomain.getVarIniConditions()) {
                    Expression iniExp = varIniCondition.getIniVal();
                    try {
                        iniExp.bindExpression(this);
                    } catch (Exception ex) {
                        ex.printStackTrace(System.out);
                        setWarning(ex.getMessage());
                    }
                }
                // check probability rate
                for (JumpProcess jumpProcess : subDomain.getJumpProcesses()) {
                    Expression probExp = jumpProcess.getProbabilityRate();
                    try {
                        probExp.bindExpression(this);
                    } catch (Exception ex) {
                        ex.printStackTrace(System.out);
                        setWarning(ex.getMessage());
                    }
                }
            } else if (isRuleBased()) {
            } else {
                // ODE model
                // 
                // Check that all equations are ODEs
                // 
                int odeCount = 0;
                Enumeration<Equation> enum_equ = subDomain.getEquations();
                while (enum_equ.hasMoreElements()) {
                    Equation equ = enum_equ.nextElement();
                    if (equ instanceof OdeEquation) {
                        odeCount++;
                    } else {
                        Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_CompartmentalModel, VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_MODEL_3, Issue.SEVERITY_ERROR);
                        issueList.add(issue);
                    }
                }
                if (odeCount == 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_CompartmentalModel, VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_MODEL_4, Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (volVarCount != odeCount) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_CompartmentalModel, VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_MODEL_5, Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (memVarCount > 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_CompartmentalModel, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_MODEL_6, VCML.MembraneVariable), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (filVarCount > 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_CompartmentalModel, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_MODEL_6, VCML.FilamentVariable), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (volRegionVarCount > 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_CompartmentalModel, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_MODEL_6, VCML.VolumeRegionVariable), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (memRegionVarCount > 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_CompartmentalModel, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_MODEL_6, VCML.MembraneRegionVariable), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (filRegionVarCount > 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_CompartmentalModel, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_COMPARTMENT_MODEL_6, VCML.FilamentRegionVariable), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
            }
        }
    // 
    // spatial (PDE and ODE)
    // 
    } else {
        // 
        // Check that the number of CompartmentSubdomains equals the number of VolumeSubVolumes in the Geometry
        // Check that the number of FilamentSubdomains equals the number of Filaments in the Geometry
        // 
        int compartmentCount = 0;
        int membraneCount = 0;
        int filamentCount = 0;
        int pointCount = 0;
        for (int i = 0; i < subDomainList.size(); i++) {
            SubDomain subDomain = (SubDomain) subDomainList.get(i);
            if (subDomain instanceof CompartmentSubDomain) {
                if (geometry.getGeometrySpec().getSubVolume(subDomain.getName()) == null) {
                    Issue issue = new Issue(subDomain, issueContext, IssueCategory.MathDescription_SpatialModel_Subdomain, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_1, subDomain.getName()), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                compartmentCount++;
            } else if (subDomain instanceof MembraneSubDomain) {
                membraneCount++;
            } else if (subDomain instanceof FilamentSubDomain) {
                filamentCount++;
            } else if (subDomain instanceof PointSubDomain) {
                pointCount++;
            } else {
                Issue issue = new Issue(subDomain, issueContext, IssueCategory.MathDescription_SpatialModel_Subdomain, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_2, subDomain.getName()), Issue.SEVERITY_ERROR);
                issueList.add(issue);
            }
        }
        if (geometry.getGeometrySpec().getNumSubVolumes() != compartmentCount) {
            Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_SpatialModel, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_3, geometry.getGeometrySpec().getNumSubVolumes(), compartmentCount), Issue.SEVERITY_ERROR);
            issueList.add(issue);
        }
        if (geometry.getGeometrySpec().getFilamentGroup().getFilamentCount() != filamentCount) {
        // setWarning("Spatial model, there are "+geometry.getGeometrySpec().getFilamentGroup().getFilamentCount()+" filaments in geometry, but "+filamentCount+" "+VCML.FilamentSubDomain+"'s, must be equal");
        // return false;
        }
        if (filamentCount == 0 && (filVarCount > 0 || filRegionVarCount > 0)) {
            Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_SpatialModel, VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_4, Issue.SEVERITY_ERROR);
            issueList.add(issue);
        }
        if (membraneCount == 0 && (memVarCount > 0 || memRegionVarCount > 0)) {
            Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_SpatialModel, VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_5, Issue.SEVERITY_ERROR);
            issueList.add(issue);
        }
        // 
        for (int i = 0; i < subDomainList.size(); i++) {
            SubDomain subDomain1 = (SubDomain) subDomainList.get(i);
            for (int j = 0; j < subDomainList.size(); j++) {
                if (i != j) {
                    SubDomain subDomain2 = (SubDomain) subDomainList.get(j);
                    if (subDomain1.getName().equals(subDomain2.getName())) {
                        Issue issue = new Issue(subDomain1, issueContext, IssueCategory.MathDescription_SpatialModel_Subdomain, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_6, subDomain1.getName(), subDomain2.getName()), Issue.SEVERITY_ERROR);
                        issueList.add(issue);
                    }
                    if (subDomain1 instanceof MembraneSubDomain && subDomain2 instanceof MembraneSubDomain) {
                        MembraneSubDomain memSubDomain1 = (MembraneSubDomain) subDomain1;
                        MembraneSubDomain memSubDomain2 = (MembraneSubDomain) subDomain2;
                        if ((memSubDomain1.getInsideCompartment() == memSubDomain2.getInsideCompartment() && memSubDomain1.getOutsideCompartment() == memSubDomain2.getOutsideCompartment()) || (memSubDomain1.getInsideCompartment() == memSubDomain2.getOutsideCompartment() && memSubDomain1.getOutsideCompartment() == memSubDomain2.getInsideCompartment())) {
                            Issue issue = new Issue(subDomain1, issueContext, IssueCategory.MathDescription_SpatialModel_Subdomain, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_7, memSubDomain1.getInsideCompartment().getName(), memSubDomain1.getOutsideCompartment().getName()), Issue.SEVERITY_ERROR);
                            issueList.add(issue);
                        }
                    }
                }
            }
        }
        // check periodic boundary conditons
        for (int i = 0; i < subDomainList.size(); i++) {
            SubDomain subDomain = (SubDomain) subDomainList.get(i);
            if (subDomain instanceof CompartmentSubDomain) {
                CompartmentSubDomain compartmentSubDomain = (CompartmentSubDomain) subDomain;
                BoundaryConditionType bctM = compartmentSubDomain.getBoundaryConditionXm();
                BoundaryConditionType bctP = compartmentSubDomain.getBoundaryConditionXp();
                if (bctM.isPERIODIC() && !bctP.isPERIODIC() || !bctM.isPERIODIC() && bctP.isPERIODIC()) {
                    Issue issue = new Issue(subDomain, issueContext, IssueCategory.MathDescription_SpatialModel_Subdomain, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_9, "Xm", "Xp", subDomain.getName()), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                bctM = compartmentSubDomain.getBoundaryConditionYm();
                bctP = compartmentSubDomain.getBoundaryConditionYp();
                if (bctM.isPERIODIC() && !bctP.isPERIODIC() || !bctM.isPERIODIC() && bctP.isPERIODIC()) {
                    Issue issue = new Issue(subDomain, issueContext, IssueCategory.MathDescription_SpatialModel_Subdomain, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_9, "Ym", "Yp", subDomain.getName()), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                bctM = compartmentSubDomain.getBoundaryConditionZm();
                bctP = compartmentSubDomain.getBoundaryConditionZp();
                if (bctM.isPERIODIC() && !bctP.isPERIODIC() || !bctM.isPERIODIC() && bctP.isPERIODIC()) {
                    Issue issue = new Issue(subDomain, issueContext, IssueCategory.MathDescription_SpatialModel_Subdomain, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_9, "Zm", "Zp", subDomain.getName()), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
            } else if (subDomain instanceof MembraneSubDomain) {
                MembraneSubDomain membraneSubDomain = (MembraneSubDomain) subDomain;
                BoundaryConditionType bctM = membraneSubDomain.getBoundaryConditionXm();
                BoundaryConditionType bctP = membraneSubDomain.getBoundaryConditionXp();
                if (bctM.isPERIODIC() && !bctP.isPERIODIC() || !bctM.isPERIODIC() && bctP.isPERIODIC()) {
                    Issue issue = new Issue(subDomain, issueContext, IssueCategory.MathDescription_SpatialModel_Subdomain, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_9, "Xm", "Xp", subDomain.getName()), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                bctM = membraneSubDomain.getBoundaryConditionYm();
                bctP = membraneSubDomain.getBoundaryConditionYp();
                if (bctM.isPERIODIC() && !bctP.isPERIODIC() || !bctM.isPERIODIC() && bctP.isPERIODIC()) {
                    Issue issue = new Issue(subDomain, issueContext, IssueCategory.MathDescription_SpatialModel_Subdomain, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_9, "Ym", "Yp", subDomain.getName()), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                bctM = membraneSubDomain.getBoundaryConditionZm();
                bctP = membraneSubDomain.getBoundaryConditionZp();
                if (bctM.isPERIODIC() && !bctP.isPERIODIC() || !bctM.isPERIODIC() && bctP.isPERIODIC()) {
                    Issue issue = new Issue(subDomain, issueContext, IssueCategory.MathDescription_SpatialModel_Subdomain, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_9, "Zm", "Zp", subDomain.getName()), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
            }
        }
        try {
            if (geometry.getGeometrySpec().getDimension() > 0) {
                // 
                // Check that there is a MembraneSubdomain for each unique subVolume-subVolume interface in Geometry
                // each ResolvedSurfaceLocation is an instance of a subVolume-subVolume interface (one-to-one with region boundaries).
                // 
                GeometricRegion[] regions = geometry.getGeometrySurfaceDescription().getGeometricRegions();
                // }
                if (regions == null) {
                    Issue issue = new Issue(geometry, issueContext, IssueCategory.MathDescription_SpatialModel_Geometry, VCellErrorMessages.MATH_DESCRIPTION_GEOMETRY_2, Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                } else {
                    for (int i = 0; i < regions.length; i++) {
                        if (regions[i] instanceof SurfaceGeometricRegion) {
                            SurfaceGeometricRegion surfaceRegion = (SurfaceGeometricRegion) regions[i];
                            SubVolume subVolume1 = ((VolumeGeometricRegion) surfaceRegion.getAdjacentGeometricRegions()[0]).getSubVolume();
                            CompartmentSubDomain compartment1 = getCompartmentSubDomain(subVolume1.getName());
                            if (compartment1 == null) {
                                Issue issue = new Issue(geometry, issueContext, IssueCategory.MathDescription_SpatialModel_Geometry, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_GEOMETRY_3, getGeometry().getName(), subVolume1.getName()), Issue.SEVERITY_ERROR);
                                issueList.add(issue);
                            }
                            SubVolume subVolume2 = ((VolumeGeometricRegion) surfaceRegion.getAdjacentGeometricRegions()[1]).getSubVolume();
                            CompartmentSubDomain compartment2 = getCompartmentSubDomain(subVolume2.getName());
                            if (compartment2 == null) {
                                Issue issue = new Issue(geometry, issueContext, IssueCategory.MathDescription_SpatialModel_Geometry, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_GEOMETRY_3, getGeometry().getName(), subVolume2.getName()), Issue.SEVERITY_ERROR);
                                issueList.add(issue);
                            }
                            MembraneSubDomain membraneSubDomain = getMembraneSubDomain(compartment1, compartment2);
                            if (compartment2 != null && compartment1 != null && membraneSubDomain == null) {
                                Issue issue = new Issue(geometry, issueContext, IssueCategory.MathDescription_SpatialModel_Geometry, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_GEOMETRY_4, compartment1.getName(), compartment2.getName()), Issue.SEVERITY_ERROR);
                                issueList.add(issue);
                            }
                        }
                    }
                    // 
                    for (int i = 0; i < subDomainList.size(); i++) {
                        if (subDomainList.get(i) instanceof MembraneSubDomain) {
                            MembraneSubDomain membraneSubDomain = (MembraneSubDomain) subDomainList.get(i);
                            boolean bFoundSurfaceInGeometry = false;
                            for (int j = 0; j < regions.length; j++) {
                                if (regions[j] instanceof SurfaceGeometricRegion) {
                                    SurfaceGeometricRegion surfaceRegion = (SurfaceGeometricRegion) regions[j];
                                    VolumeGeometricRegion volumeRegion1 = (VolumeGeometricRegion) surfaceRegion.getAdjacentGeometricRegions()[0];
                                    VolumeGeometricRegion volumeRegion2 = (VolumeGeometricRegion) surfaceRegion.getAdjacentGeometricRegions()[1];
                                    String memInsideName = membraneSubDomain.getInsideCompartment().getName();
                                    String memOutsideName = membraneSubDomain.getOutsideCompartment().getName();
                                    if ((memInsideName.equals(volumeRegion1.getSubVolume().getName()) && memOutsideName.equals(volumeRegion2.getSubVolume().getName())) || (memInsideName.equals(volumeRegion2.getSubVolume().getName()) && memOutsideName.equals(volumeRegion1.getSubVolume().getName()))) {
                                        bFoundSurfaceInGeometry = true;
                                        break;
                                    }
                                }
                            }
                            if (!bFoundSurfaceInGeometry) {
                                Issue issue = new Issue(geometry, issueContext, IssueCategory.MathDescription_SpatialModel_Geometry, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_GEOMETRY_5, membraneSubDomain.getInsideCompartment().getName(), membraneSubDomain.getOutsideCompartment().getName()), Issue.SEVERITY_ERROR);
                                issueList.add(issue);
                            }
                        }
                    }
                }
            }
        // }catch (GeometryException e){
        // e.printStackTrace(System.out);
        // setWarning("error validating MathDescription: "+e.getMessage());
        // return false;
        // }catch (ImageException e){
        // e.printStackTrace(System.out);
        // setWarning("error validating MathDescription: "+e.getMessage());
        // return false;
        // }catch (ExpressionException e){
        // e.printStackTrace(System.out);
        // setWarning("error validating MathDescription: "+e.getMessage());
        // return false;
        } catch (Exception e) {
            e.printStackTrace(System.out);
            Issue issue = new Issue(geometry, issueContext, IssueCategory.MathDescription_SpatialModel_Geometry, e.getMessage(), Issue.SEVERITY_ERROR);
            issueList.add(issue);
        }
        // 
        for (int i = 0; i < variableList.size(); i++) {
            Variable var = variableList.get(i);
            String varName = var.getName();
            if (var instanceof VolVariable) {
                VolVariable volVar = (VolVariable) var;
                int pdeRefCount = 0;
                int odeRefCount = 0;
                int steadyPdeCount = 0;
                int measureCount = 0;
                for (int j = 0; j < subDomainList.size(); j++) {
                    SubDomain subDomain = subDomainList.get(j);
                    Equation equ = subDomain.getEquation(volVar);
                    if (equ instanceof PdeEquation) {
                        if (((PdeEquation) equ).isSteady()) {
                            steadyPdeCount++;
                        } else {
                            pdeRefCount++;
                        }
                        // 
                        for (int k = 0; k < subDomainList.size(); k++) {
                            SubDomain subDomain2 = subDomainList.get(k);
                            if (subDomain2 instanceof MembraneSubDomain) {
                                MembraneSubDomain membraneSubDomain = (MembraneSubDomain) subDomain2;
                                if (membraneSubDomain.getInsideCompartment() == subDomain || membraneSubDomain.getOutsideCompartment() == subDomain) {
                                    JumpCondition jumpCondition = membraneSubDomain.getJumpCondition(volVar);
                                    BoundaryConditionValue boundaryValue = ((PdeEquation) equ).getBoundaryConditionValue(membraneSubDomain.getName());
                                    // if PDE variable does not have jump condition OR boundaryValue (neither or both are not allowed), its an error.
                                    if ((jumpCondition == null && boundaryValue == null) || (jumpCondition != null && boundaryValue != null)) {
                                        Issue issue = new Issue(equ, issueContext, IssueCategory.MathDescription_SpatialModel_Equation, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_10, varName, subDomain.getName(), membraneSubDomain.getName()), Issue.SEVERITY_ERROR);
                                        issueList.add(issue);
                                    }
                                    if (boundaryValue != null && (subDomain.getBoundaryConditionSpec(membraneSubDomain.getName()) == null)) {
                                        Issue issue = new Issue(equ, issueContext, IssueCategory.MathDescription_SpatialModel_Equation, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_10A, varName, subDomain.getName(), membraneSubDomain.getName(), membraneSubDomain.getName(), subDomain.getName()), Issue.SEVERITY_ERROR);
                                        issueList.add(issue);
                                    }
                                }
                            }
                        }
                    } else if (equ instanceof OdeEquation) {
                        odeRefCount++;
                    } else if (equ instanceof MeasureEquation) {
                        measureCount++;
                    }
                    // 
                    if (subDomain instanceof MembraneSubDomain) {
                        MembraneSubDomain memSubDomain = (MembraneSubDomain) subDomain;
                        JumpCondition jumpCondition = memSubDomain.getJumpCondition(volVar);
                        if (jumpCondition != null) {
                            boolean bInsidePresent = (memSubDomain.getInsideCompartment().getEquation(volVar) instanceof PdeEquation);
                            boolean bOutsidePresent = (memSubDomain.getOutsideCompartment().getEquation(volVar) instanceof PdeEquation);
                            if (!bInsidePresent && !bOutsidePresent) {
                                Issue issue = new Issue(equ, issueContext, IssueCategory.MathDescription_SpatialModel_Equation, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_11, varName, memSubDomain.getName(), memSubDomain.getInsideCompartment().getName(), memSubDomain.getOutsideCompartment().getName()), Issue.SEVERITY_ERROR);
                                issueList.add(issue);
                            }
                            // 
                            if (!bInsidePresent && !jumpCondition.getInFluxExpression().isZero()) {
                                Issue issue = new Issue(equ, issueContext, IssueCategory.MathDescription_SpatialModel_Equation, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_12, varName, memSubDomain.getName(), memSubDomain.getInsideCompartment().getName()), Issue.SEVERITY_ERROR);
                                issueList.add(issue);
                            }
                            if (!bOutsidePresent && !jumpCondition.getOutFluxExpression().isZero()) {
                                Issue issue = new Issue(equ, issueContext, IssueCategory.MathDescription_SpatialModel_Equation, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_13, varName, memSubDomain.getName(), memSubDomain.getOutsideCompartment().getName()), Issue.SEVERITY_ERROR);
                                issueList.add(issue);
                            }
                        }
                    }
                }
                if (odeRefCount > 0 && pdeRefCount > 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_SpatialModel, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_14, varName), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (steadyPdeCount > 0 && pdeRefCount > 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_SpatialModel, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_15, varName), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (odeRefCount == 0 && pdeRefCount == 0 && steadyPdeCount == 0 && measureCount == 0) {
                    Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_SpatialModel, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_16, varName), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
            } else // 
            if (var instanceof MemVariable) {
                int pdeRefCount = 0;
                int odeRefCount = 0;
                int steadyPdeCount = 0;
                for (int j = 0; j < subDomainList.size(); j++) {
                    SubDomain subDomain = subDomainList.get(j);
                    Equation equ = subDomain.getEquation(var);
                    if (equ instanceof PdeEquation) {
                        if (((PdeEquation) equ).isSteady()) {
                            steadyPdeCount++;
                        } else {
                            pdeRefCount++;
                        }
                    } else if (equ instanceof OdeEquation) {
                        odeRefCount++;
                    }
                }
                if (odeRefCount > 0 && pdeRefCount > 0) {
                    Issue issue = new Issue(var, issueContext, IssueCategory.MathDescription_SpatialModel_Variable, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_14, varName), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (steadyPdeCount > 0 && pdeRefCount > 0) {
                    Issue issue = new Issue(var, issueContext, IssueCategory.MathDescription_SpatialModel_Variable, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_15, varName), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
                if (odeRefCount == 0 && pdeRefCount == 0 && steadyPdeCount == 0) {
                    Issue issue = new Issue(var, issueContext, IssueCategory.MathDescription_SpatialModel_Variable, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_16, varName), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
            } else // 
            if (var instanceof FilamentVariable) {
                for (int j = 0; j < subDomainList.size(); j++) {
                    SubDomain subDomain = subDomainList.get(j);
                    if (subDomain instanceof FilamentSubDomain) {
                        Equation equ = subDomain.getEquation(var);
                        if (!(equ instanceof OdeEquation)) {
                            Issue issue = new Issue(var, issueContext, IssueCategory.MathDescription_SpatialModel_Variable, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_21, varName, subDomain.getName()), Issue.SEVERITY_ERROR);
                            issueList.add(issue);
                        }
                    }
                }
            } else // 
            if (var instanceof VolumeRegionVariable) {
                VolumeRegionVariable volRegionVar = (VolumeRegionVariable) var;
                int count = 0;
                for (int j = 0; j < subDomainList.size(); j++) {
                    SubDomain subDomain = subDomainList.get(j);
                    if (subDomain instanceof CompartmentSubDomain) {
                        Equation equ = subDomain.getEquation(volRegionVar);
                        if (equ instanceof VolumeRegionEquation) {
                            count++;
                            // 
                            for (int k = 0; k < subDomainList.size(); k++) {
                                SubDomain subDomain2 = subDomainList.get(k);
                                if (subDomain2 instanceof MembraneSubDomain) {
                                    MembraneSubDomain membraneSubDomain = (MembraneSubDomain) subDomain2;
                                    if (membraneSubDomain.getInsideCompartment() == subDomain || membraneSubDomain.getOutsideCompartment() == subDomain) {
                                        if (membraneSubDomain.getJumpCondition(volRegionVar) == null) {
                                            Issue issue = new Issue(var, issueContext, IssueCategory.MathDescription_SpatialModel_Variable, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_17, varName, subDomain.getName(), membraneSubDomain.getName()), Issue.SEVERITY_ERROR);
                                            issueList.add(issue);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (count == 0) {
                    Issue issue = new Issue(var, issueContext, IssueCategory.MathDescription_SpatialModel_Variable, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_18, varName), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
            } else // 
            if (var instanceof MembraneRegionVariable) {
                int count = 0;
                for (int j = 0; j < subDomainList.size(); j++) {
                    SubDomain subDomain = subDomainList.get(j);
                    if (subDomain instanceof MembraneSubDomain) {
                        Equation equ = subDomain.getEquation(var);
                        if (equ instanceof MembraneRegionEquation) {
                            count++;
                        }
                    }
                }
                if (count == 0) {
                    Issue issue = new Issue(var, issueContext, IssueCategory.MathDescription_SpatialModel_Variable, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_19, varName), Issue.SEVERITY_ERROR);
                    issueList.add(issue);
                }
            } else // 
            if (var instanceof FilamentRegionVariable) {
                for (int j = 0; j < subDomainList.size(); j++) {
                    SubDomain subDomain = subDomainList.get(j);
                    if (subDomain instanceof FilamentSubDomain) {
                        Equation equ = subDomain.getEquation(var);
                        if (!(equ instanceof FilamentRegionEquation)) {
                            Issue issue = new Issue(var, issueContext, IssueCategory.MathDescription_SpatialModel_Variable, VCellErrorMessages.getErrorMessage(VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_20, varName, subDomain.getName()), Issue.SEVERITY_ERROR);
                            issueList.add(issue);
                        }
                    }
                }
            }
        }
    }
    if (eventList.size() > 0 && isSpatial()) {
        Issue issue = new Issue(this, issueContext, IssueCategory.MathDescription_SpatialModel, VCellErrorMessages.MATH_DESCRIPTION_SPATIAL_MODEL_22, Issue.SEVERITY_ERROR);
        issueList.add(issue);
    }
    for (Event event : eventList) {
        try {
            event.bind(this);
        } catch (ExpressionBindingException e) {
            Issue issue = new Issue(event, issueContext, IssueCategory.MathDescription_SpatialModel_Event, e.getMessage(), Issue.SEVERITY_ERROR);
            issueList.add(issue);
        }
    }
    for (DataGenerator dataGenerator : postProcessingBlock.getDataGeneratorList()) {
        try {
            dataGenerator.bind(this);
        } catch (ExpressionBindingException e) {
            Issue issue = new Issue(dataGenerator, issueContext, IssueCategory.MathDescription_SpatialModel_PostProcessingBlock, e.getMessage(), Issue.SEVERITY_ERROR);
            issueList.add(issue);
        }
    }
}
Also used : Issue(org.vcell.util.Issue) ExpressionException(cbit.vcell.parser.ExpressionException) SubVolume(cbit.vcell.geometry.SubVolume) VolumeGeometricRegion(cbit.vcell.geometry.surface.VolumeGeometricRegion) VolumeGeometricRegion(cbit.vcell.geometry.surface.VolumeGeometricRegion) SurfaceGeometricRegion(cbit.vcell.geometry.surface.SurfaceGeometricRegion) GeometricRegion(cbit.vcell.geometry.surface.GeometricRegion) SurfaceGeometricRegion(cbit.vcell.geometry.surface.SurfaceGeometricRegion) ExpressionBindingException(cbit.vcell.parser.ExpressionBindingException) ExpressionBindingException(cbit.vcell.parser.ExpressionBindingException) NoSuchElementException(java.util.NoSuchElementException) ExpressionException(cbit.vcell.parser.ExpressionException) BoundaryConditionValue(cbit.vcell.math.PdeEquation.BoundaryConditionValue) Expression(cbit.vcell.parser.Expression) ChangeEvent(javax.swing.event.ChangeEvent)

Example 45 with ExpressionException

use of cbit.vcell.parser.ExpressionException in project vcell by virtualcell.

the class PdeEquation method testConstant.

private boolean testConstant(MathSymbolTable simSymbolTable, Expression exp) {
    if (exp == null) {
        return true;
    }
    if (exp.isZero()) {
        return true;
    }
    Expression newExp = new Expression(exp);
    try {
        newExp.bindExpression(simSymbolTable);
        newExp = simSymbolTable.substituteFunctions(newExp);
        newExp = newExp.flatten();
        newExp.evaluateConstant();
    } catch (ExpressionException ex) {
        return false;
    } catch (MathException ex) {
        return false;
    }
    return true;
}
Also used : Expression(cbit.vcell.parser.Expression) ExpressionException(cbit.vcell.parser.ExpressionException)

Aggregations

ExpressionException (cbit.vcell.parser.ExpressionException)199 Expression (cbit.vcell.parser.Expression)138 MathException (cbit.vcell.math.MathException)58 PropertyVetoException (java.beans.PropertyVetoException)51 DataAccessException (org.vcell.util.DataAccessException)34 ArrayList (java.util.ArrayList)32 Variable (cbit.vcell.math.Variable)30 IOException (java.io.IOException)29 Element (org.jdom.Element)26 ExpressionBindingException (cbit.vcell.parser.ExpressionBindingException)25 MappingException (cbit.vcell.mapping.MappingException)24 Function (cbit.vcell.math.Function)24 Vector (java.util.Vector)24 ModelException (cbit.vcell.model.ModelException)23 SolverException (cbit.vcell.solver.SolverException)23 CompartmentSubDomain (cbit.vcell.math.CompartmentSubDomain)22 VCUnitDefinition (cbit.vcell.units.VCUnitDefinition)21 Constant (cbit.vcell.math.Constant)20 MathDescription (cbit.vcell.math.MathDescription)19 Structure (cbit.vcell.model.Structure)18