Search in sources :

Example 1 with MembraneRegionEquation

use of cbit.vcell.math.MembraneRegionEquation in project vcell by virtualcell.

the class XmlReader method getMembraneRegionEquation.

/**
 * This method returns a MembraneRegionEquation from a XML Element.
 * Creation date: (5/17/2001 3:52:40 PM)
 * @return cbit.vcell.math.MembraneRegionEquation
 * @param param org.jdom.Element
 * @exception cbit.vcell.xml.XmlParseException The exception description.
 */
private MembraneRegionEquation getMembraneRegionEquation(Element param, MathDescription mathDesc) throws XmlParseException {
    // get attributes
    String varname = unMangle(param.getAttributeValue(XMLTags.NameAttrTag));
    // find reference in the dictionnary
    // try a MembraneRegionVariable
    MembraneRegionVariable varref = (MembraneRegionVariable) mathDesc.getVariable(varname);
    if (varref == null) {
        throw new XmlParseException("The reference to the MembraneRegion variable " + varname + " could not be resolved!");
    }
    // get Initial condition
    String temp = param.getChildText(XMLTags.InitialTag, vcNamespace);
    Expression exp;
    exp = unMangleExpression(temp);
    // ** Create the Equation **
    MembraneRegionEquation memRegEq = new MembraneRegionEquation(varref, exp);
    // set the Uniform Rate
    temp = param.getChildText(XMLTags.UniformRateTag, vcNamespace);
    exp = unMangleExpression(temp);
    memRegEq.setUniformRateExpression(exp);
    // set the Membrane Rate
    temp = param.getChildText(XMLTags.MembraneRateTag, vcNamespace);
    exp = unMangleExpression(temp);
    memRegEq.setMembraneRateExpression(exp);
    return memRegEq;
}
Also used : MembraneRegionVariable(cbit.vcell.math.MembraneRegionVariable) Expression(cbit.vcell.parser.Expression) MembraneRegionEquation(cbit.vcell.math.MembraneRegionEquation)

Example 2 with MembraneRegionEquation

use of cbit.vcell.math.MembraneRegionEquation in project vcell by virtualcell.

the class MathMapping_4_8 method refreshMathDescription.

/**
 * This method was created in VisualAge.
 */
private void refreshMathDescription() throws MappingException, MatrixException, MathException, ExpressionException, ModelException {
    // All sizes must be set for new ODE models and ratios must be set for old ones.
    simContext.checkValidity();
    // 
    // temporarily place all variables in a hashtable (before binding) and discarding duplicates (check for equality)
    // 
    VariableHash varHash = new VariableHash();
    StructureMapping[] structureMappings = simContext.getGeometryContext().getStructureMappings();
    Model model = simContext.getModel();
    StructureTopology structTopology = model.getStructureTopology();
    // 
    // verify that all structures are mapped to subvolumes and all subvolumes are mapped to a structure
    // 
    Structure[] structures = simContext.getGeometryContext().getModel().getStructures();
    for (int i = 0; i < structures.length; i++) {
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(structures[i]);
        if (sm == null || (sm instanceof FeatureMapping && getSubVolume((FeatureMapping) sm) == null)) {
            throw new MappingException("model structure '" + structures[i].getName() + "' not mapped to a geometry subdomain");
        }
        if (sm != null && (sm instanceof MembraneMapping) && ((MembraneMapping) sm).getVolumeFractionParameter() != null) {
            Expression volFractExp = ((MembraneMapping) sm).getVolumeFractionParameter().getExpression();
            if (volFractExp != null) {
                try {
                    double volFract = volFractExp.evaluateConstant();
                    if (volFract >= 1.0) {
                        throw new MappingException("model structure '" + structTopology.getInsideFeature(((MembraneMapping) sm).getMembrane()).getName() + "' has volume fraction >= 1.0");
                    }
                } catch (ExpressionException e) {
                }
            }
        }
    }
    SubVolume[] subVolumes = simContext.getGeometryContext().getGeometry().getGeometrySpec().getSubVolumes();
    for (int i = 0; i < subVolumes.length; i++) {
        if (getStructures(subVolumes[i]) == null || getStructures(subVolumes[i]).length == 0) {
            throw new MappingException("geometry subdomain '" + subVolumes[i].getName() + "' not mapped from a model structure");
        }
    }
    // deals with model parameters
    Hashtable<VolVariable, EventAssignmentInitParameter> eventVolVarHash = new Hashtable<VolVariable, EventAssignmentInitParameter>();
    ModelParameter[] modelParameters = model.getModelParameters();
    if (simContext.getGeometry().getDimension() == 0) {
        // 
        // global parameters from model (that presently are constants)
        // 
        BioEvent[] bioEvents = simContext.getBioEvents();
        ArrayList<SymbolTableEntry> eventAssignTargets = new ArrayList<SymbolTableEntry>();
        if (bioEvents != null && bioEvents.length > 0) {
            for (BioEvent be : bioEvents) {
                for (EventAssignment ea : be.getEventAssignments()) {
                    if (!eventAssignTargets.contains(ea.getTarget())) {
                        eventAssignTargets.add(ea.getTarget());
                    }
                }
            }
        }
        for (int j = 0; j < modelParameters.length; j++) {
            Expression modelParamExpr = getIdentifierSubstitutions(modelParameters[j].getExpression(), modelParameters[j].getUnitDefinition(), null);
            if (eventAssignTargets.contains(modelParameters[j])) {
                EventAssignmentInitParameter eap = null;
                try {
                    eap = addEventAssignmentInitParameter(modelParameters[j].getName(), modelParameters[j].getExpression(), PARAMETER_ROLE_EVENTASSIGN_INITCONDN, modelParameters[j].getUnitDefinition());
                } catch (PropertyVetoException e) {
                    e.printStackTrace(System.out);
                    throw new MappingException(e.getMessage());
                }
                // varHash.addVariable(newFunctionOrConstant(getMathSymbol(eap, null), modelParamExpr));
                VolVariable volVar = new VolVariable(modelParameters[j].getName(), nullDomain);
                varHash.addVariable(volVar);
                eventVolVarHash.put(volVar, eap);
            } else {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(modelParameters[j], null), modelParamExpr));
            }
        }
    } else {
        // 
        for (int pass = 0; pass < 2; pass++) {
            for (int j = 0; j < modelParameters.length; j++) {
                Hashtable<String, Expression> structMappingVariantsHash = new Hashtable<String, Expression>();
                for (int k = 0; k < structureMappings.length; k++) {
                    String paramVariantName = null;
                    Expression paramVariantExpr = null;
                    if (modelParameters[j].getExpression().getSymbols() == null) {
                        paramVariantName = modelParameters[j].getName();
                        paramVariantExpr = getIdentifierSubstitutions(modelParameters[j].getExpression(), modelParameters[j].getUnitDefinition(), null);
                    } else {
                        paramVariantName = modelParameters[j].getName() + "_" + TokenMangler.fixTokenStrict(structureMappings[k].getStructure().getName());
                        // if the expression has symbols that do not belong in that structureMapping, do not create the variant.
                        Expression exp1 = modelParameters[j].getExpression();
                        Expression flattenedModelParamExpr = substituteGlobalParameters(exp1);
                        String[] symbols = flattenedModelParamExpr.getSymbols();
                        boolean bValid = true;
                        Structure sm_struct = structureMappings[k].getStructure();
                        if (symbols != null) {
                            for (int ii = 0; ii < symbols.length; ii++) {
                                SpeciesContext sc = model.getSpeciesContext(symbols[ii]);
                                if (sc != null) {
                                    // symbol[ii] is a speciesContext, check its structure with structureMapping[k].structure. If they are the same or
                                    // if it is the adjacent membrane(s), allow variant expression to be created. Else, continue.
                                    Structure sp_struct = sc.getStructure();
                                    if (sp_struct.compareEqual(sm_struct)) {
                                        bValid = bValid && true;
                                    } else {
                                        // if the 2 structures are not the same, are they adjacent? then 'bValid' is true, else false.
                                        if ((sm_struct instanceof Feature) && (sp_struct instanceof Membrane)) {
                                            Feature sm_feature = (Feature) sm_struct;
                                            Membrane sp_mem = (Membrane) sp_struct;
                                            if (sp_mem.compareEqual(structTopology.getParentStructure(sm_feature)) || (structTopology.getInsideFeature(sp_mem).compareEqual(sm_feature) || structTopology.getOutsideFeature(sp_mem).compareEqual(sm_feature))) {
                                                bValid = bValid && true;
                                            } else {
                                                bValid = bValid && false;
                                                break;
                                            }
                                        } else if ((sm_struct instanceof Membrane) && (sp_struct instanceof Feature)) {
                                            Feature sp_feature = (Feature) sp_struct;
                                            Membrane sm_mem = (Membrane) sm_struct;
                                            if (sm_mem.compareEqual(structTopology.getParentStructure(sp_feature)) || (structTopology.getInsideFeature(sm_mem).compareEqual(sp_feature) || structTopology.getOutsideFeature(sm_mem).compareEqual(sp_feature))) {
                                                bValid = bValid && true;
                                            } else {
                                                bValid = bValid && false;
                                                break;
                                            }
                                        } else {
                                            bValid = bValid && false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        if (bValid) {
                            if (pass == 0) {
                                paramVariantExpr = new Expression("VCELL_TEMPORARY_EXPRESSION_PLACEHOLDER");
                            } else {
                                paramVariantExpr = getIdentifierSubstitutions(modelParameters[j].getExpression(), modelParameters[j].getUnitDefinition(), structureMappings[k]);
                            }
                        }
                    }
                    if (paramVariantExpr != null) {
                        structMappingVariantsHash.put(paramVariantName, paramVariantExpr);
                    }
                }
                globalParamVariantsHash.put(modelParameters[j], structMappingVariantsHash);
            }
        }
        // 
        for (int j = 0; j < modelParameters.length; j++) {
            if (modelParameters[j].getExpression().getSymbols() == null) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(modelParameters[j], null), getIdentifierSubstitutions(modelParameters[j].getExpression(), modelParameters[j].getUnitDefinition(), null)));
            } else {
                Hashtable<String, Expression> smVariantsHash = globalParamVariantsHash.get(modelParameters[j]);
                for (int k = 0; k < structureMappings.length; k++) {
                    String variantName = modelParameters[j].getName() + "_" + TokenMangler.fixTokenStrict(structureMappings[k].getStructure().getName());
                    Expression variantExpr = smVariantsHash.get(variantName);
                    if (variantExpr != null) {
                        varHash.addVariable(newFunctionOrConstant(variantName, variantExpr));
                    }
                }
            }
        }
    }
    // 
    // gather only those reactionSteps that are not "excluded"
    // 
    ReactionSpec[] reactionSpecs = simContext.getReactionContext().getReactionSpecs();
    Vector<ReactionStep> rsList = new Vector<ReactionStep>();
    for (int i = 0; i < reactionSpecs.length; i++) {
        if (reactionSpecs[i].isExcluded() == false) {
            rsList.add(reactionSpecs[i].getReactionStep());
        }
    }
    ReactionStep[] reactionSteps = new ReactionStep[rsList.size()];
    rsList.copyInto(reactionSteps);
    // 
    for (int i = 0; i < reactionSteps.length; i++) {
        Kinetics.UnresolvedParameter[] unresolvedParameters = reactionSteps[i].getKinetics().getUnresolvedParameters();
        if (unresolvedParameters != null && unresolvedParameters.length > 0) {
            StringBuffer buffer = new StringBuffer();
            for (int j = 0; j < unresolvedParameters.length; j++) {
                if (j > 0) {
                    buffer.append(", ");
                }
                buffer.append(unresolvedParameters[j].getName());
            }
            throw new MappingException(reactionSteps[i].getDisplayType() + " '" + reactionSteps[i].getName() + "' contains unresolved identifier(s): " + buffer);
        }
    }
    // 
    // create new MathDescription (based on simContext's previous MathDescription if possible)
    // 
    MathDescription oldMathDesc = simContext.getMathDescription();
    mathDesc = null;
    if (oldMathDesc != null) {
        if (oldMathDesc.getVersion() != null) {
            mathDesc = new MathDescription(oldMathDesc.getVersion());
        } else {
            mathDesc = new MathDescription(oldMathDesc.getName());
        }
    } else {
        mathDesc = new MathDescription(simContext.getName() + "_generated");
    }
    // 
    // volume variables
    // 
    Enumeration<SpeciesContextMapping> enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = enum1.nextElement();
        if (scm.getVariable() instanceof VolVariable) {
            if (!(mathDesc.getVariable(scm.getVariable().getName()) instanceof VolVariable)) {
                varHash.addVariable(scm.getVariable());
            }
        }
    }
    // 
    // membrane variables
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() instanceof MemVariable) {
            varHash.addVariable(scm.getVariable());
        }
    }
    varHash.addVariable(new Constant(getMathSymbol(model.getFARADAY_CONSTANT(), null), getIdentifierSubstitutions(model.getFARADAY_CONSTANT().getExpression(), model.getFARADAY_CONSTANT().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getFARADAY_CONSTANT_NMOLE(), null), getIdentifierSubstitutions(model.getFARADAY_CONSTANT_NMOLE().getExpression(), model.getFARADAY_CONSTANT_NMOLE().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getGAS_CONSTANT(), null), getIdentifierSubstitutions(model.getGAS_CONSTANT().getExpression(), model.getGAS_CONSTANT().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getTEMPERATURE(), null), getIdentifierSubstitutions(new Expression(simContext.getTemperatureKelvin()), model.getTEMPERATURE().getUnitDefinition(), null)));
    // 
    // only calculate potential if at least one MembraneMapping has CalculateVoltage == true
    // 
    boolean bCalculatePotential = false;
    for (int i = 0; i < structureMappings.length; i++) {
        if (structureMappings[i] instanceof MembraneMapping) {
            if (((MembraneMapping) structureMappings[i]).getCalculateVoltage()) {
                bCalculatePotential = true;
            }
        }
    }
    // (simContext.getGeometry().getDimension() == 0);
    potentialMapping = new PotentialMapping(simContext, this);
    potentialMapping.computeMath();
    if (bCalculatePotential) {
        // 
        // copy functions for currents and constants for capacitances
        // 
        ElectricalDevice[] devices = potentialMapping.getElectricalDevices();
        for (int j = 0; j < devices.length; j++) {
            if (devices[j] instanceof MembraneElectricalDevice) {
                MembraneElectricalDevice membraneElectricalDevice = (MembraneElectricalDevice) devices[j];
                MembraneMapping memMapping = membraneElectricalDevice.getMembraneMapping();
                Parameter specificCapacitanceParm = memMapping.getParameterFromRole(MembraneMapping.ROLE_SpecificCapacitance);
                varHash.addVariable(new Constant(getMathSymbol(specificCapacitanceParm, memMapping), getIdentifierSubstitutions(specificCapacitanceParm.getExpression(), specificCapacitanceParm.getUnitDefinition(), memMapping)));
                ElectricalDevice.ElectricalDeviceParameter transmembraneCurrentParm = membraneElectricalDevice.getParameterFromRole(ElectricalDevice.ROLE_TransmembraneCurrent);
                ElectricalDevice.ElectricalDeviceParameter totalCurrentParm = membraneElectricalDevice.getParameterFromRole(ElectricalDevice.ROLE_TotalCurrent);
                ElectricalDevice.ElectricalDeviceParameter capacitanceParm = membraneElectricalDevice.getParameterFromRole(ElectricalDevice.ROLE_Capacitance);
                if (totalCurrentParm != null && /* totalCurrentDensityParm.getExpression()!=null && */
                memMapping.getCalculateVoltage()) {
                    Expression totalCurrentDensityExp = (totalCurrentParm.getExpression() != null) ? (totalCurrentParm.getExpression()) : (new Expression(0.0));
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrentParm, membraneElectricalDevice.getMembraneMapping()), getIdentifierSubstitutions(totalCurrentDensityExp, totalCurrentParm.getUnitDefinition(), membraneElectricalDevice.getMembraneMapping())));
                }
                if (transmembraneCurrentParm != null && transmembraneCurrentParm.getExpression() != null && memMapping.getCalculateVoltage()) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(transmembraneCurrentParm, membraneElectricalDevice.getMembraneMapping()), getIdentifierSubstitutions(transmembraneCurrentParm.getExpression(), transmembraneCurrentParm.getUnitDefinition(), membraneElectricalDevice.getMembraneMapping())));
                }
                if (capacitanceParm != null && capacitanceParm.getExpression() != null && memMapping.getCalculateVoltage()) {
                    StructureMappingParameter sizeParameter = membraneElectricalDevice.getMembraneMapping().getSizeParameter();
                    if (simContext.getGeometry().getDimension() == 0 && (sizeParameter.getExpression() == null || sizeParameter.getExpression().isZero())) {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(capacitanceParm, membraneElectricalDevice.getMembraneMapping()), getIdentifierSubstitutions(Expression.mult(memMapping.getNullSizeParameterValue(), specificCapacitanceParm.getExpression()), capacitanceParm.getUnitDefinition(), membraneElectricalDevice.getMembraneMapping())));
                    } else {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(capacitanceParm, membraneElectricalDevice.getMembraneMapping()), getIdentifierSubstitutions(capacitanceParm.getExpression(), capacitanceParm.getUnitDefinition(), membraneElectricalDevice.getMembraneMapping())));
                    }
                }
                // 
                if (membraneElectricalDevice.getDependentVoltageExpression() == null) {
                    // is Voltage Independent?
                    StructureMapping.StructureMappingParameter initialVoltageParm = memMapping.getInitialVoltageParameter();
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(initialVoltageParm, memMapping), getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), memMapping)));
                } else // 
                // membrane forced potential
                // 
                {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(memMapping.getMembrane().getMembraneVoltage(), memMapping), getIdentifierSubstitutions(membraneElectricalDevice.getDependentVoltageExpression(), memMapping.getMembrane().getMembraneVoltage().getUnitDefinition(), memMapping)));
                }
            } else if (devices[j] instanceof CurrentClampElectricalDevice) {
                CurrentClampElectricalDevice currentClampDevice = (CurrentClampElectricalDevice) devices[j];
                // total current = current source (no capacitance)
                Parameter totalCurrentParm = currentClampDevice.getParameterFromRole(CurrentClampElectricalDevice.ROLE_TotalCurrent);
                Parameter currentParm = currentClampDevice.getParameterFromRole(CurrentClampElectricalDevice.ROLE_TransmembraneCurrent);
                // Parameter dependentVoltage = currentClampDevice.getCurrentClampStimulus().getVoltageParameter();
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrentParm, null), getIdentifierSubstitutions(totalCurrentParm.getExpression(), totalCurrentParm.getUnitDefinition(), null)));
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(currentParm, null), getIdentifierSubstitutions(currentParm.getExpression(), currentParm.getUnitDefinition(), null)));
                // varHash.addVariable(newFunctionOrConstant(getMathSymbol(dependentVoltage,null),getIdentifierSubstitutions(currentClampDevice.getDependentVoltageExpression(),dependentVoltage.getUnitDefinition(),null)));
                // 
                // add user-defined parameters
                // 
                ElectricalDevice.ElectricalDeviceParameter[] parameters = currentClampDevice.getParameters();
                for (int k = 0; k < parameters.length; k++) {
                    if (parameters[k].getExpression() != null) {
                        // guards against voltage parameters that are "variable".
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameters[k], null), getIdentifierSubstitutions(parameters[k].getExpression(), parameters[k].getUnitDefinition(), null)));
                    }
                }
            } else if (devices[j] instanceof VoltageClampElectricalDevice) {
                VoltageClampElectricalDevice voltageClampDevice = (VoltageClampElectricalDevice) devices[j];
                // total current = current source (no capacitance)
                Parameter totalCurrent = voltageClampDevice.getParameterFromRole(VoltageClampElectricalDevice.ROLE_TotalCurrent);
                Parameter totalCurrentParm = voltageClampDevice.getParameterFromRole(VoltageClampElectricalDevice.ROLE_TotalCurrent);
                Parameter voltageParm = voltageClampDevice.getParameterFromRole(VoltageClampElectricalDevice.ROLE_Voltage);
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrent, null), getIdentifierSubstitutions(totalCurrent.getExpression(), totalCurrent.getUnitDefinition(), null)));
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrentParm, null), getIdentifierSubstitutions(totalCurrentParm.getExpression(), totalCurrentParm.getUnitDefinition(), null)));
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(voltageParm, null), getIdentifierSubstitutions(voltageParm.getExpression(), voltageParm.getUnitDefinition(), null)));
                // 
                // add user-defined parameters
                // 
                ElectricalDevice.ElectricalDeviceParameter[] parameters = voltageClampDevice.getParameters();
                for (int k = 0; k < parameters.length; k++) {
                    if (parameters[k].getRole() == ElectricalDevice.ROLE_UserDefined) {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameters[k], null), getIdentifierSubstitutions(parameters[k].getExpression(), parameters[k].getUnitDefinition(), null)));
                    }
                }
            }
        }
    } else {
        // 
        for (int j = 0; j < structureMappings.length; j++) {
            if (structureMappings[j] instanceof MembraneMapping) {
                MembraneMapping memMapping = (MembraneMapping) structureMappings[j];
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(memMapping.getMembrane().getMembraneVoltage(), memMapping), getIdentifierSubstitutions(memMapping.getInitialVoltageParameter().getExpression(), memMapping.getInitialVoltageParameter().getUnitDefinition(), memMapping)));
            }
        }
    }
    // 
    for (int j = 0; j < structureMappings.length; j++) {
        if (structureMappings[j] instanceof MembraneMapping) {
            MembraneMapping membraneMapping = (MembraneMapping) structureMappings[j];
            Membrane.MembraneVoltage membraneVoltage = membraneMapping.getMembrane().getMembraneVoltage();
            ElectricalDevice[] membraneDevices = potentialMapping.getElectricalDevices(membraneMapping.getMembrane());
            // ElectricalDevice membraneDevice = null;
            for (int i = 0; i < membraneDevices.length; i++) {
                if (membraneDevices[i].hasCapacitance() && membraneDevices[i].getDependentVoltageExpression() == null) {
                    if (membraneMapping.getCalculateVoltage() && bCalculatePotential) {
                        if (getResolved(membraneMapping)) {
                            // 
                            if (mathDesc.getVariable(Membrane.MEMBRANE_VOLTAGE_REGION_NAME) == null) {
                                // varHash.addVariable(new MembraneRegionVariable(MembraneVoltage.MEMBRANE_VOLTAGE_REGION_NAME));
                                varHash.addVariable(new MembraneRegionVariable(getMathSymbol(membraneVoltage, membraneMapping), nullDomain));
                            }
                        } else {
                            // 
                            // spatially unresolved membrane, and must solve for potential ... make VolVariable for this compartment
                            // 
                            varHash.addVariable(new VolVariable(getMathSymbol(membraneVoltage, membraneMapping), nullDomain));
                        }
                        Parameter initialVoltageParm = membraneMapping.getInitialVoltageParameter();
                        Variable initVoltageFunction = newFunctionOrConstant(getMathSymbol(initialVoltageParm, membraneMapping), getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), membraneMapping));
                        varHash.addVariable(initVoltageFunction);
                    } else {
                        // 
                        // don't calculate voltage, still may need it though
                        // 
                        Parameter initialVoltageParm = membraneMapping.getInitialVoltageParameter();
                        Variable voltageFunction = newFunctionOrConstant(getMathSymbol(membraneMapping.getMembrane().getMembraneVoltage(), membraneMapping), getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), membraneMapping));
                        varHash.addVariable(voltageFunction);
                    }
                }
            }
        }
    }
    // 
    for (int j = 0; j < reactionSteps.length; j++) {
        ReactionStep rs = reactionSteps[j];
        if (simContext.getReactionContext().getReactionSpec(rs).isExcluded()) {
            continue;
        }
        Kinetics.KineticsParameter[] parameters = rs.getKinetics().getKineticsParameters();
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(rs.getStructure());
        if (parameters != null) {
            for (int i = 0; i < parameters.length; i++) {
                if (((parameters[i].getRole() == Kinetics.ROLE_CurrentDensity) || (parameters[i].getRole() == Kinetics.ROLE_LumpedCurrent)) && (parameters[i].getExpression() == null || parameters[i].getExpression().isZero())) {
                    continue;
                }
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameters[i], sm), getIdentifierSubstitutions(parameters[i].getExpression(), parameters[i].getUnitDefinition(), sm)));
            }
        }
    }
    // 
    // initial constants (either function or constant)
    // 
    SpeciesContextSpec[] speciesContextSpecs = simContext.getReactionContext().getSpeciesContextSpecs();
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpecParameter initParm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration);
        if (initParm != null) {
            Expression initExpr = new Expression(initParm.getExpression());
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
            String[] symbols = initExpr.getSymbols();
            // Check if 'initExpr' has other speciesContexts in its expression, need to replace it with 'spContext_init'
            for (int j = 0; symbols != null && j < symbols.length; j++) {
                // if symbol is a speciesContext, replacing it with a reference to initial condition for that speciesContext.
                SpeciesContext spC = null;
                SymbolTableEntry ste = initExpr.getSymbolBinding(symbols[j]);
                if (ste instanceof SpeciesContextSpecProxyParameter) {
                    SpeciesContextSpecProxyParameter spspp = (SpeciesContextSpecProxyParameter) ste;
                    if (spspp.getTarget() instanceof SpeciesContext) {
                        spC = (SpeciesContext) spspp.getTarget();
                        SpeciesContextSpec spcspec = simContext.getReactionContext().getSpeciesContextSpec(spC);
                        SpeciesContextSpecParameter spCInitParm = spcspec.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration);
                        // if initConc param expression is null, try initCount
                        if (spCInitParm.getExpression() == null) {
                            spCInitParm = spcspec.getParameterFromRole(SpeciesContextSpec.ROLE_InitialCount);
                        }
                        // need to get init condn expression, but can't get it from getMathSymbol() (mapping between bio and math), hence get it as below.
                        Expression scsInitExpr = new Expression(spCInitParm, getNameScope());
                        // scsInitExpr.bindExpression(this);
                        initExpr.substituteInPlace(new Expression(spC.getName()), scsInitExpr);
                    }
                }
            }
            // now create the appropriate function for the current speciesContextSpec.
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(initParm, sm), getIdentifierSubstitutions(initExpr, initParm.getUnitDefinition(), sm)));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextMapping scm = getSpeciesContextMapping(speciesContextSpecs[i].getSpeciesContext());
        SpeciesContextSpec.SpeciesContextSpecParameter diffParm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_DiffusionRate);
        if (diffParm != null && (scm.isPDERequired())) {
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(diffParm, sm), getIdentifierSubstitutions(diffParm.getExpression(), diffParm.getUnitDefinition(), sm)));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpec.SpeciesContextSpecParameter bc_xm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueXm);
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
        if (bc_xm != null && (bc_xm.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_xm, sm), getIdentifierSubstitutions(bc_xm.getExpression(), bc_xm.getUnitDefinition(), sm)));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_xp = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueXp);
        if (bc_xp != null && (bc_xp.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_xp, sm), getIdentifierSubstitutions(bc_xp.getExpression(), bc_xp.getUnitDefinition(), sm)));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_ym = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueYm);
        if (bc_ym != null && (bc_ym.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_ym, sm), getIdentifierSubstitutions(bc_ym.getExpression(), bc_ym.getUnitDefinition(), sm)));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_yp = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueYp);
        if (bc_yp != null && (bc_yp.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_yp, sm), getIdentifierSubstitutions(bc_yp.getExpression(), bc_yp.getUnitDefinition(), sm)));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_zm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueZm);
        if (bc_zm != null && (bc_zm.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_zm, sm), getIdentifierSubstitutions(bc_zm.getExpression(), bc_zm.getUnitDefinition(), sm)));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_zp = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueZp);
        if (bc_zp != null && (bc_zp.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_zp, sm), getIdentifierSubstitutions(bc_zp.getExpression(), bc_zp.getUnitDefinition(), sm)));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velX = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityX);
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
        if (advection_velX != null && (advection_velX.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velX, sm), getIdentifierSubstitutions(advection_velX.getExpression(), advection_velX.getUnitDefinition(), sm)));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velY = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityY);
        if (advection_velY != null && (advection_velY.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velY, sm), getIdentifierSubstitutions(advection_velY.getExpression(), advection_velY.getUnitDefinition(), sm)));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velZ = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityZ);
        if (advection_velZ != null && (advection_velZ.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velZ, sm), getIdentifierSubstitutions(advection_velZ.getExpression(), advection_velZ.getUnitDefinition(), sm)));
        }
    }
    // 
    // constant species (either function or constant)
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() instanceof Constant) {
            varHash.addVariable(scm.getVariable());
        }
    }
    // 
    // conversion factors
    // 
    varHash.addVariable(new Constant(getMathSymbol(model.getKMOLE(), null), getIdentifierSubstitutions(model.getKMOLE().getExpression(), model.getKMOLE().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(model.getN_PMOLE().getName(), getIdentifierSubstitutions(model.getN_PMOLE().getExpression(), model.getN_PMOLE().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(model.getKMILLIVOLTS().getName(), getIdentifierSubstitutions(model.getKMILLIVOLTS().getExpression(), model.getKMILLIVOLTS().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(model.getK_GHK().getName(), getIdentifierSubstitutions(model.getK_GHK().getExpression(), model.getK_GHK().getUnitDefinition(), null)));
    // 
    // geometric functions
    // 
    ModelUnitSystem modelUnitSystem = simContext.getModel().getUnitSystem();
    VCUnitDefinition lengthInverseUnit = modelUnitSystem.getLengthUnit().getInverse();
    for (int i = 0; i < structureMappings.length; i++) {
        StructureMapping sm = structureMappings[i];
        Parameter parm = sm.getParameterFromRole(StructureMapping.ROLE_VolumeFraction);
        if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
        }
        parm = sm.getParameterFromRole(StructureMapping.ROLE_SurfaceToVolumeRatio);
        if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
        }
        if (sm instanceof MembraneMapping && !getResolved(sm)) {
            MembraneMapping mm = (MembraneMapping) sm;
            parm = ((MembraneMapping) sm).getVolumeFractionParameter();
            if (parm.getExpression() == null) {
                throw new MappingException("volume fraction not specified for feature '" + structTopology.getInsideFeature(mm.getMembrane()).getName() + "', please refer to Structure Mapping in Application '" + simContext.getName() + "'");
            }
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), modelUnitSystem.getInstance_DIMENSIONLESS(), sm)));
            parm = mm.getSurfaceToVolumeParameter();
            if (parm.getExpression() == null) {
                throw new MappingException("surface to volume ratio not specified for membrane '" + mm.getMembrane().getName() + "', please refer to Structure Mapping in Application '" + simContext.getName() + "'");
            }
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), lengthInverseUnit, sm)));
        }
        StructureMappingParameter sizeParm = sm.getSizeParameter();
        if (sizeParm != null) {
            if (simContext.getGeometry().getDimension() == 0) {
                if (sizeParm.getExpression() != null) {
                    try {
                        double value = sizeParm.getExpression().evaluateConstant();
                        varHash.addVariable(new Constant(getMathSymbol(sizeParm, sm), new Expression(value)));
                    } catch (ExpressionException e) {
                        // varHash.addVariable(new Function(getMathSymbol(parm,sm),getIdentifierSubstitutions(parm.getExpression(),parm.getUnitDefinition(),sm)));
                        e.printStackTrace(System.out);
                        throw new MappingException("Size of structure:" + sm.getNameScope().getName() + " cannot be evaluated as constant.");
                    }
                }
            } else {
                String compartmentName = null;
                VCUnitDefinition sizeUnit = sm.getSizeParameter().getUnitDefinition();
                String sizeFunctionName = null;
                if (sm instanceof MembraneMapping) {
                    MembraneMapping mm = (MembraneMapping) sm;
                    if (getResolved(mm)) {
                        FeatureMapping fm_inside = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getInsideFeature(mm.getMembrane()));
                        FeatureMapping fm_outside = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getOutsideFeature(mm.getMembrane()));
                        compartmentName = getSubVolume(fm_inside).getName() + "_" + getSubVolume(fm_outside).getName();
                        sizeFunctionName = MathFunctionDefinitions.Function_regionArea_current.getFunctionName();
                    } else {
                        FeatureMapping fm_inside = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getInsideFeature(mm.getMembrane()));
                        FeatureMapping fm_outside = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getOutsideFeature(mm.getMembrane()));
                        if (getSubVolume(fm_inside) == getSubVolume(fm_outside)) {
                            compartmentName = getSubVolume(fm_inside).getName();
                            sizeFunctionName = MathFunctionDefinitions.Function_regionVolume_current.getFunctionName();
                        } else {
                            throw new RuntimeException("unexpected structure mapping for membrane '" + mm.getMembrane().getName() + "'");
                        }
                    }
                } else if (sm instanceof FeatureMapping) {
                    FeatureMapping fm = (FeatureMapping) sm;
                    compartmentName = getSubVolume(fm).getName();
                    sizeFunctionName = MathFunctionDefinitions.Function_regionVolume_current.getFunctionName();
                } else {
                    throw new RuntimeException("structure mapping " + sm.getClass().getName() + " not yet supported");
                }
                Expression totalVolumeCorrection = sm.getStructureSizeCorrection(simContext, this);
                Expression sizeFunctionExpression = Expression.function(sizeFunctionName, new Expression[] { new Expression("'" + compartmentName + "'") });
                sizeFunctionExpression.bindExpression(mathDesc);
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(sizeParm, sm), getIdentifierSubstitutions(Expression.mult(totalVolumeCorrection, sizeFunctionExpression), sizeUnit, sm)));
                parm = sm.getParameterFromRole(StructureMapping.ROLE_AreaPerUnitArea);
                if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SurfaceClass) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
                }
                parm = sm.getParameterFromRole(StructureMapping.ROLE_AreaPerUnitVolume);
                if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
                }
                parm = sm.getParameterFromRole(StructureMapping.ROLE_VolumePerUnitArea);
                if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SurfaceClass) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
                }
                parm = sm.getParameterFromRole(StructureMapping.ROLE_VolumePerUnitVolume);
                if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
                }
            }
        }
    }
    // 
    for (int i = 0; i < fieldMathMappingParameters.length; i++) {
        varHash.addVariable(newFunctionOrConstant(getMathSymbol(fieldMathMappingParameters[i], null), getIdentifierSubstitutions(fieldMathMappingParameters[i].getExpression(), fieldMathMappingParameters[i].getUnitDefinition(), null)));
    }
    // 
    // functions
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() == null && scm.getDependencyExpression() != null) {
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(scm.getSpeciesContext().getStructure());
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(scm.getSpeciesContext(), sm), getIdentifierSubstitutions(scm.getDependencyExpression(), scm.getSpeciesContext().getUnitDefinition(), sm)));
        }
    }
    // 
    // set Variables to MathDescription all at once with the order resolved by "VariableHash"
    // 
    mathDesc.setAllVariables(varHash.getAlphabeticallyOrderedVariables());
    // 
    if (simContext.getGeometryContext().getGeometry() != null) {
        try {
            mathDesc.setGeometry(simContext.getGeometryContext().getGeometry());
        } catch (java.beans.PropertyVetoException e) {
            e.printStackTrace(System.out);
            throw new MappingException("failure setting geometry " + e.getMessage());
        }
    } else {
        throw new MappingException("geometry must be defined");
    }
    // 
    // volume subdomains
    // 
    subVolumes = simContext.getGeometryContext().getGeometry().getGeometrySpec().getSubVolumes();
    VCUnitDefinition timeUnit = modelUnitSystem.getTimeUnit();
    for (int j = 0; j < subVolumes.length; j++) {
        SubVolume subVolume = (SubVolume) subVolumes[j];
        // 
        // get priority of subDomain
        // 
        int priority;
        Feature spatialFeature = getResolvedFeature(subVolume);
        if (spatialFeature == null) {
            if (simContext.getGeometryContext().getGeometry().getDimension() > 0) {
                throw new MappingException("no compartment (in Physiology) is mapped to subdomain '" + subVolume.getName() + "' (in Geometry)");
            } else {
                priority = CompartmentSubDomain.NON_SPATIAL_PRIORITY;
            }
        } else {
            // now does not have to match spatial feature, *BUT* needs to be unique
            priority = j;
        }
        // 
        // create subDomain
        // 
        CompartmentSubDomain subDomain = new CompartmentSubDomain(subVolume.getName(), priority);
        mathDesc.addSubDomain(subDomain);
        // 
        if (spatialFeature != null) {
            FeatureMapping fm = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(spatialFeature);
            subDomain.setBoundaryConditionXm(fm.getBoundaryConditionTypeXm());
            subDomain.setBoundaryConditionXp(fm.getBoundaryConditionTypeXp());
            if (simContext.getGeometry().getDimension() > 1) {
                subDomain.setBoundaryConditionYm(fm.getBoundaryConditionTypeYm());
                subDomain.setBoundaryConditionYp(fm.getBoundaryConditionTypeYp());
            }
            if (simContext.getGeometry().getDimension() > 2) {
                subDomain.setBoundaryConditionZm(fm.getBoundaryConditionTypeZm());
                subDomain.setBoundaryConditionZp(fm.getBoundaryConditionTypeZp());
            }
        }
        // 
        // create equations
        // 
        VolumeStructureAnalyzer structureAnalyzer = getVolumeStructureAnalyzer(subVolume);
        Enumeration<SpeciesContextMapping> enumSCM = getSpeciesContextMappings();
        while (enumSCM.hasMoreElements()) {
            SpeciesContextMapping scm = enumSCM.nextElement();
            // 
            if (scm.getVariable() instanceof VolVariable && scm.getDependencyExpression() == null) {
                SpeciesContext sc = scm.getSpeciesContext();
                StructureMapping sm = simContext.getGeometryContext().getStructureMapping(sc.getStructure());
                SpeciesContextSpec scs = simContext.getReactionContext().getSpeciesContextSpec(sc);
                VolVariable variable = (VolVariable) scm.getVariable();
                Equation equation = null;
                if ((scm.isPDERequired()) && sm instanceof FeatureMapping) {
                    // 
                    if (getSubVolume((FeatureMapping) sm) == subVolume) {
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), sm));
                        Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()));
                        Expression diffusion = new Expression(getMathSymbol(scs.getDiffusionParameter(), sm));
                        equation = new PdeEquation(variable, initial, rate, diffusion);
                        ((PdeEquation) equation).setBoundaryXm((scs.getBoundaryXmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXmParameter(), sm)));
                        ((PdeEquation) equation).setBoundaryXp((scs.getBoundaryXpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXpParameter(), sm)));
                        ((PdeEquation) equation).setBoundaryYm((scs.getBoundaryYmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYmParameter(), sm)));
                        ((PdeEquation) equation).setBoundaryYp((scs.getBoundaryYpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYpParameter(), sm)));
                        ((PdeEquation) equation).setBoundaryZm((scs.getBoundaryZmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZmParameter(), sm)));
                        ((PdeEquation) equation).setBoundaryZp((scs.getBoundaryZpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZpParameter(), sm)));
                        ((PdeEquation) equation).setVelocityX((scs.getVelocityXParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getVelocityXParameter(), sm)));
                        ((PdeEquation) equation).setVelocityY((scs.getVelocityYParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getVelocityYParameter(), sm)));
                        ((PdeEquation) equation).setVelocityZ((scs.getVelocityZParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getVelocityZParameter(), sm)));
                        subDomain.replaceEquation(equation);
                    } else {
                        Expression initial = new Expression(0.0);
                        Expression rate = new Expression(0.0);
                        Expression diffusion = new Expression(getMathSymbol(scs.getDiffusionParameter(), sm));
                        equation = new PdeEquation(variable, initial, rate, diffusion);
                        if (subDomain.getEquation(variable) == null) {
                            subDomain.addEquation(equation);
                        }
                    }
                } else {
                    // 
                    // ODE
                    // 
                    SubVolume mappedSubVolume = null;
                    if (sm instanceof FeatureMapping) {
                        mappedSubVolume = getSubVolume((FeatureMapping) sm);
                    } else if (sm instanceof MembraneMapping) {
                        // membrane is mapped to that of the inside feature
                        FeatureMapping featureMapping = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getInsideFeature((Membrane) sm.getStructure()));
                        mappedSubVolume = getSubVolume(featureMapping);
                    }
                    if (mappedSubVolume == subVolume) {
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), null));
                        Expression rate = (scm.getRate() == null) ? new Expression(0.0) : getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()));
                        equation = new OdeEquation(variable, initial, rate);
                        subDomain.replaceEquation(equation);
                    } else {
                        Expression initial = new Expression(0.0);
                        Expression rate = new Expression(0.0);
                        equation = new OdeEquation(variable, initial, rate);
                        if (subDomain.getEquation(variable) == null) {
                            subDomain.addEquation(equation);
                        }
                    }
                }
            }
        }
        // 
        // create fast system (if neccessary)
        // 
        SpeciesContextMapping[] fastSpeciesContextMappings = structureAnalyzer.getFastSpeciesContextMappings();
        VCUnitDefinition subDomainUnit = modelUnitSystem.getVolumeConcentrationUnit();
        if (fastSpeciesContextMappings != null) {
            FastSystem fastSystem = new FastSystem(mathDesc);
            for (int i = 0; i < fastSpeciesContextMappings.length; i++) {
                SpeciesContextMapping scm = fastSpeciesContextMappings[i];
                if (scm.getFastInvariant() == null) {
                    // 
                    // independant-fast variable, create a fastRate object
                    // 
                    Expression rate = getIdentifierSubstitutions(scm.getFastRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(getResolvedFeature(subVolume)));
                    FastRate fastRate = new FastRate(rate);
                    fastSystem.addFastRate(fastRate);
                } else {
                    // 
                    // dependant-fast variable, create a fastInvariant object
                    // 
                    Expression rate = getIdentifierSubstitutions(scm.getFastInvariant(), subDomainUnit, simContext.getGeometryContext().getStructureMapping(getResolvedFeature(subVolume)));
                    FastInvariant fastInvariant = new FastInvariant(rate);
                    fastSystem.addFastInvariant(fastInvariant);
                }
            }
            subDomain.setFastSystem(fastSystem);
            // constructor calls the 'refresh' method which constructs depemdency matrix, dependent/independent vars and pseudoconstants, etc.
            FastSystemAnalyzer fs_analyzer = new FastSystemAnalyzer(fastSystem, mathDesc);
        }
        // 
        // create ode's for voltages to be calculated on unresolved membranes mapped to this subVolume
        // 
        Structure[] localStructures = getStructures(subVolume);
        for (int sIndex = 0; sIndex < localStructures.length; sIndex++) {
            if (localStructures[sIndex] instanceof Membrane) {
                Membrane membrane = (Membrane) localStructures[sIndex];
                MembraneMapping membraneMapping = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(membrane);
                if (!getResolved(membraneMapping) && membraneMapping.getCalculateVoltage()) {
                    MembraneElectricalDevice capacitiveDevice = potentialMapping.getCapacitiveDevice(membrane);
                    if (capacitiveDevice.getDependentVoltageExpression() == null) {
                        VolVariable vVar = (VolVariable) mathDesc.getVariable(getMathSymbol(capacitiveDevice.getVoltageSymbol(), membraneMapping));
                        Expression initExp = new Expression(getMathSymbol(capacitiveDevice.getMembraneMapping().getInitialVoltageParameter(), membraneMapping));
                        subDomain.addEquation(new OdeEquation(vVar, initExp, getIdentifierSubstitutions(potentialMapping.getOdeRHS(capacitiveDevice, this), membrane.getMembraneVoltage().getUnitDefinition().divideBy(timeUnit), membraneMapping)));
                    } else {
                    // 
                    // 
                    // 
                    }
                }
            }
        }
    }
    // 
    for (int k = 0; k < subVolumes.length; k++) {
        SubVolume subVolume = (SubVolume) subVolumes[k];
        // 
        // if there is a spatially resolved membrane surrounding this subVolume, then create a membraneSubDomain
        // 
        structures = getStructures(subVolume);
        Membrane membrane = null;
        if (structures != null) {
            for (int j = 0; j < structures.length; j++) {
                if (structures[j] instanceof Membrane && getResolved(simContext.getGeometryContext().getStructureMapping(structures[j]))) {
                    membrane = (Membrane) structures[j];
                }
            }
        }
        if (membrane == null) {
            continue;
        }
        SubVolume outerSubVolume = getSubVolume(((FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getOutsideFeature(membrane))));
        SubVolume innerSubVolume = getSubVolume(((FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getInsideFeature(membrane))));
        if (innerSubVolume != subVolume) {
            throw new MappingException("membrane " + membrane.getName() + " improperly mapped to inner subVolume " + innerSubVolume.getName());
        }
        // 
        // get priority of subDomain
        // 
        // Feature spatialFeature = simContext.getGeometryContext().getResolvedFeature(subVolume);
        // int priority = spatialFeature.getPriority();
        // 
        // create subDomain
        // 
        CompartmentSubDomain outerCompartment = mathDesc.getCompartmentSubDomain(outerSubVolume.getName());
        CompartmentSubDomain innerCompartment = mathDesc.getCompartmentSubDomain(innerSubVolume.getName());
        SurfaceClass surfaceClass = simContext.getGeometry().getGeometrySurfaceDescription().getSurfaceClass(innerSubVolume, outerSubVolume);
        MembraneSubDomain memSubDomain = new MembraneSubDomain(innerCompartment, outerCompartment, surfaceClass.getName());
        mathDesc.addSubDomain(memSubDomain);
        // 
        // create equations for membrane-bound molecular species
        // 
        MembraneStructureAnalyzer membraneStructureAnalyzer = getMembraneStructureAnalyzer(membrane);
        Enumeration<SpeciesContextMapping> enumSCM = getSpeciesContextMappings();
        while (enumSCM.hasMoreElements()) {
            SpeciesContextMapping scm = enumSCM.nextElement();
            SpeciesContext sc = scm.getSpeciesContext();
            SpeciesContextSpec scs = simContext.getReactionContext().getSpeciesContextSpec(sc);
            // 
            if ((scm.getVariable() instanceof MemVariable) && scm.getDependencyExpression() == null) {
                // 
                // independant variable, create an equation object
                // 
                Equation equation = null;
                MemVariable variable = (MemVariable) scm.getVariable();
                MembraneMapping mm = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(sc.getStructure());
                if (scm.isPDERequired()) {
                    // 
                    if (mm.getMembrane() == membrane) {
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), mm));
                        Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()));
                        Expression diffusion = new Expression(getMathSymbol(scs.getDiffusionParameter(), mm));
                        equation = new PdeEquation(variable, initial, rate, diffusion);
                        ((PdeEquation) equation).setBoundaryXm((scs.getBoundaryXmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXmParameter(), mm)));
                        ((PdeEquation) equation).setBoundaryXp((scs.getBoundaryXpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXpParameter(), mm)));
                        ((PdeEquation) equation).setBoundaryYm((scs.getBoundaryYmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYmParameter(), mm)));
                        ((PdeEquation) equation).setBoundaryYp((scs.getBoundaryYpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYpParameter(), mm)));
                        ((PdeEquation) equation).setBoundaryZm((scs.getBoundaryZmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZmParameter(), mm)));
                        ((PdeEquation) equation).setBoundaryZp((scs.getBoundaryZpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZpParameter(), mm)));
                        memSubDomain.replaceEquation(equation);
                    } else {
                        Expression initial = new Expression(0.0);
                        Expression rate = new Expression(0.0);
                        Expression diffusion = new Expression(getMathSymbol(scs.getDiffusionParameter(), mm));
                        equation = new PdeEquation(variable, initial, rate, diffusion);
                        if (memSubDomain.getEquation(variable) == null) {
                            memSubDomain.addEquation(equation);
                        }
                    }
                } else {
                    // 
                    if (mm.getMembrane() == membrane) {
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), null));
                        Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()));
                        equation = new OdeEquation(variable, initial, rate);
                        memSubDomain.replaceEquation(equation);
                    } else {
                        Expression initial = new Expression(0.0);
                        Expression rate = new Expression(0.0);
                        equation = new OdeEquation(variable, initial, rate);
                        if (memSubDomain.getEquation(variable) == null) {
                            memSubDomain.addEquation(equation);
                        }
                    }
                }
            }
        }
        // 
        // create dummy jump conditions for all volume variables that diffuse and/or advect
        // 
        Enumeration<SpeciesContextMapping> enum_scm = getSpeciesContextMappings();
        while (enum_scm.hasMoreElements()) {
            SpeciesContextMapping scm = enum_scm.nextElement();
            if (scm.isPDERequired()) {
                // Species species = scm.getSpeciesContext().getSpecies();
                Variable var = scm.getVariable();
                if (var instanceof VolVariable && (scm.isPDERequired())) {
                    JumpCondition jc = memSubDomain.getJumpCondition((VolVariable) var);
                    if (jc == null) {
                        // System.out.println("MathMapping.refreshMathDescription(), adding jump condition for diffusing variable "+var.getName()+" on membrane "+membraneStructureAnalyzer.getMembrane().getName());
                        jc = new JumpCondition((VolVariable) var);
                        memSubDomain.addJumpCondition(jc);
                    }
                }
            }
        }
        // 
        // create jump conditions for any volume variables that bind to membrane or have explicitly defined fluxes
        // 
        ResolvedFlux[] resolvedFluxes = membraneStructureAnalyzer.getResolvedFluxes();
        if (resolvedFluxes != null) {
            for (int i = 0; i < resolvedFluxes.length; i++) {
                Species species = resolvedFluxes[i].getSpecies();
                SpeciesContext sc = simContext.getReactionContext().getModel().getSpeciesContext(species, structTopology.getInsideFeature(membraneStructureAnalyzer.getMembrane()));
                if (sc == null) {
                    sc = simContext.getReactionContext().getModel().getSpeciesContext(species, structTopology.getOutsideFeature(membraneStructureAnalyzer.getMembrane()));
                }
                SpeciesContextMapping scm = getSpeciesContextMapping(sc);
                // if (scm.getVariable() instanceof VolVariable && scm.isDiffusing()){
                if (scm.getVariable() instanceof VolVariable && ((MembraneStructureAnalyzer.bNoFluxIfFixed || (scm.isPDERequired())))) {
                    if (MembraneStructureAnalyzer.bNoFluxIfFixed && !scm.isPDERequired()) {
                        MembraneStructureAnalyzer.bNoFluxIfFixedExercised = true;
                    }
                    JumpCondition jc = memSubDomain.getJumpCondition((VolVariable) scm.getVariable());
                    if (jc == null) {
                        jc = new JumpCondition((VolVariable) scm.getVariable());
                        memSubDomain.addJumpCondition(jc);
                    }
                    Expression inFlux = getIdentifierSubstitutions(resolvedFluxes[i].inFluxExpression, resolvedFluxes[i].getUnitDefinition(), simContext.getGeometryContext().getStructureMapping(membraneStructureAnalyzer.getMembrane()));
                    jc.setInFlux(inFlux);
                    Expression outFlux = getIdentifierSubstitutions(resolvedFluxes[i].outFluxExpression, resolvedFluxes[i].getUnitDefinition(), simContext.getGeometryContext().getStructureMapping(membraneStructureAnalyzer.getMembrane()));
                    jc.setOutFlux(outFlux);
                } else {
                    throw new MappingException("APPLICATION  " + simContext.getName() + " : " + scm.getSpeciesContext().getName() + " has spatially resolved flux at membrane " + membrane.getName() + ", but doesn't diffuse in compartment " + scm.getSpeciesContext().getStructure().getName());
                }
            }
        }
        // 
        // create fast system (if neccessary)
        // 
        SpeciesContextMapping[] fastSpeciesContextMappings = membraneStructureAnalyzer.getFastSpeciesContextMappings();
        if (fastSpeciesContextMappings != null) {
            FastSystem fastSystem = new FastSystem(mathDesc);
            for (int i = 0; i < fastSpeciesContextMappings.length; i++) {
                SpeciesContextMapping scm = fastSpeciesContextMappings[i];
                if (scm.getFastInvariant() == null) {
                    // 
                    // independant-fast variable, create a fastRate object
                    // 
                    VCUnitDefinition rateUnit = scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit);
                    MembraneMapping membraneMapping = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(membraneStructureAnalyzer.getMembrane());
                    FastRate fastRate = new FastRate(getIdentifierSubstitutions(scm.getFastRate(), rateUnit, membraneMapping));
                    fastSystem.addFastRate(fastRate);
                } else {
                    // 
                    // dependant-fast variable, create a fastInvariant object
                    // 
                    VCUnitDefinition invariantUnit = scm.getSpeciesContext().getUnitDefinition();
                    MembraneMapping membraneMapping = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(membraneStructureAnalyzer.getMembrane());
                    FastInvariant fastInvariant = new FastInvariant(getIdentifierSubstitutions(scm.getFastInvariant(), invariantUnit, membraneMapping));
                    fastSystem.addFastInvariant(fastInvariant);
                }
            }
            memSubDomain.setFastSystem(fastSystem);
            // constructor calls the 'refresh' method which constructs depemdency matrix, dependent/independent vars and pseudoconstants, etc.
            FastSystemAnalyzer fs_analyzer = new FastSystemAnalyzer(fastSystem, mathDesc);
        }
        // 
        // create Membrane-region equations for potential of this resolved membrane
        // 
        MembraneMapping membraneMapping = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(membrane);
        if (membraneMapping.getCalculateVoltage()) {
            ElectricalDevice[] membraneDevices = potentialMapping.getElectricalDevices(membrane);
            int numCapacitiveDevices = 0;
            MembraneElectricalDevice capacitiveDevice = null;
            for (int i = 0; i < membraneDevices.length; i++) {
                if (membraneDevices[i] instanceof MembraneElectricalDevice) {
                    numCapacitiveDevices++;
                    capacitiveDevice = (MembraneElectricalDevice) membraneDevices[i];
                }
            }
            if (numCapacitiveDevices != 1) {
                throw new MappingException("expecting 1 capacitive electrical device on graph edge for membrane " + membrane.getName() + ", found '" + numCapacitiveDevices + "'");
            }
            if (mathDesc.getVariable(getMathSymbol(capacitiveDevice.getVoltageSymbol(), membraneMapping)) instanceof MembraneRegionVariable) {
                MembraneRegionVariable vVar = (MembraneRegionVariable) mathDesc.getVariable(getMathSymbol(capacitiveDevice.getVoltageSymbol(), membraneMapping));
                Parameter initialVoltageParm = capacitiveDevice.getMembraneMapping().getInitialVoltageParameter();
                Expression initExp = getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), capacitiveDevice.getMembraneMapping());
                MembraneRegionEquation vEquation = new MembraneRegionEquation(vVar, initExp);
                vEquation.setMembraneRateExpression(getIdentifierSubstitutions(potentialMapping.getOdeRHS(capacitiveDevice, this), membrane.getMembraneVoltage().getUnitDefinition().divideBy(timeUnit), capacitiveDevice.getMembraneMapping()));
                memSubDomain.addEquation(vEquation);
            }
        }
    }
    // create equations for event assign targets that are model params/strutureSize, etc.
    Set<VolVariable> hashKeySet = eventVolVarHash.keySet();
    Iterator<VolVariable> volVarsIter = hashKeySet.iterator();
    // working under teh assumption that we are dealing with non-spatial math, hence only one compartment domain!
    SubDomain subDomain = mathDesc.getSubDomains().nextElement();
    while (volVarsIter.hasNext()) {
        VolVariable volVar = volVarsIter.next();
        EventAssignmentInitParameter eap = eventVolVarHash.get(volVar);
        Expression rateExpr = new Expression(0.0);
        Equation equation = new OdeEquation(volVar, new Expression(getMathSymbol(eap, null)), rateExpr);
        subDomain.addEquation(equation);
    }
    // events - add events to math desc and odes for event assignments that have parameters as target variables
    BioEvent[] bioevents = simContext.getBioEvents();
    if (bioevents != null && bioevents.length > 0) {
        for (BioEvent be : bioevents) {
            // transform the bioEvent trigger/delay to math Event
            Expression mathTriggerExpr = getIdentifierSubstitutions(be.generateTriggerExpression(), modelUnitSystem.getInstance_DIMENSIONLESS(), null);
            Delay mathDelay = null;
            if (be.getParameter(BioEventParameterType.TriggerDelay) != null) {
                boolean bUseValsFromTriggerTime = be.getUseValuesFromTriggerTime();
                Expression mathDelayExpr = getIdentifierSubstitutions(be.getParameter(BioEventParameterType.TriggerDelay).getExpression(), timeUnit, null);
                mathDelay = new Delay(bUseValsFromTriggerTime, mathDelayExpr);
            }
            // now deal with (bio)event Assignment translation to math EventAssignment
            ArrayList<EventAssignment> eventAssignments = be.getEventAssignments();
            ArrayList<Event.EventAssignment> mathEventAssignmentsList = new ArrayList<Event.EventAssignment>();
            for (EventAssignment ea : eventAssignments) {
                SymbolTableEntry ste = simContext.getEntry(ea.getTarget().getName());
                VCUnitDefinition eventAssignVarUnit = ste.getUnitDefinition();
                Variable variable = varHash.getVariable(ste.getName());
                Event.EventAssignment mathEA = new Event.EventAssignment(variable, getIdentifierSubstitutions(ea.getAssignmentExpression(), eventAssignVarUnit, null));
                mathEventAssignmentsList.add(mathEA);
            }
            // use the translated trigger, delay and event assignments to create (math) event
            Event mathEvent = new Event(be.getName(), mathTriggerExpr, mathDelay, mathEventAssignmentsList);
            mathDesc.addEvent(mathEvent);
        }
    }
    if (!mathDesc.isValid()) {
        throw new MappingException("generated an invalid mathDescription: " + mathDesc.getWarning());
    }
// System.out.println("]]]]]]]]]]]]]]]]]]]]]] VCML string begin ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
// System.out.println(mathDesc.getVCML());
// System.out.println("]]]]]]]]]]]]]]]]]]]]]] VCML string end ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
}
Also used : MembraneMapping(cbit.vcell.mapping.MembraneMapping) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) ArrayList(java.util.ArrayList) SpeciesContext(cbit.vcell.model.SpeciesContext) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Feature(cbit.vcell.model.Feature) MemVariable(cbit.vcell.math.MemVariable) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SubVolume(cbit.vcell.geometry.SubVolume) Vector(java.util.Vector) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) StructureTopology(cbit.vcell.model.Model.StructureTopology) ReactionSpec(cbit.vcell.mapping.ReactionSpec) FastInvariant(cbit.vcell.math.FastInvariant) PropertyVetoException(java.beans.PropertyVetoException) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) FastSystem(cbit.vcell.math.FastSystem) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) ReactionStep(cbit.vcell.model.ReactionStep) MembraneRegionEquation(cbit.vcell.math.MembraneRegionEquation) SurfaceClass(cbit.vcell.geometry.SurfaceClass) VariableHash(cbit.vcell.math.VariableHash) StructureMapping(cbit.vcell.mapping.StructureMapping) FeatureMapping(cbit.vcell.mapping.FeatureMapping) Structure(cbit.vcell.model.Structure) ModelUnitSystem(cbit.vcell.model.ModelUnitSystem) Hashtable(java.util.Hashtable) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Expression(cbit.vcell.parser.Expression) Model(cbit.vcell.model.Model) ProxyParameter(cbit.vcell.model.ProxyParameter) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Parameter(cbit.vcell.model.Parameter) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SpeciesContextSpecProxyParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecProxyParameter) LocalParameter(cbit.vcell.mapping.ParameterContext.LocalParameter) ModelParameter(cbit.vcell.model.Model.ModelParameter) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) BioEvent(cbit.vcell.mapping.BioEvent) Event(cbit.vcell.math.Event) BioEvent(cbit.vcell.mapping.BioEvent) MembraneRegionVariable(cbit.vcell.math.MembraneRegionVariable) MathDescription(cbit.vcell.math.MathDescription) SpeciesContextMapping(cbit.vcell.mapping.SpeciesContextMapping) SpeciesContextSpec(cbit.vcell.mapping.SpeciesContextSpec) ExpressionException(cbit.vcell.parser.ExpressionException) Delay(cbit.vcell.math.Event.Delay) MappingException(cbit.vcell.mapping.MappingException) PropertyVetoException(java.beans.PropertyVetoException) PdeEquation(cbit.vcell.math.PdeEquation) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubDomain(cbit.vcell.math.SubDomain) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) Species(cbit.vcell.model.Species) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) EventAssignment(cbit.vcell.mapping.BioEvent.EventAssignment) VolVariable(cbit.vcell.math.VolVariable) ModelParameter(cbit.vcell.model.Model.ModelParameter) OdeEquation(cbit.vcell.math.OdeEquation) JumpCondition(cbit.vcell.math.JumpCondition) MembraneRegionVariable(cbit.vcell.math.MembraneRegionVariable) VolVariable(cbit.vcell.math.VolVariable) MemVariable(cbit.vcell.math.MemVariable) Variable(cbit.vcell.math.Variable) SpeciesContextSpecProxyParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecProxyParameter) Constant(cbit.vcell.math.Constant) SymbolTableEntry(cbit.vcell.parser.SymbolTableEntry) Membrane(cbit.vcell.model.Membrane) EventAssignment(cbit.vcell.mapping.BioEvent.EventAssignment) OdeEquation(cbit.vcell.math.OdeEquation) MembraneRegionEquation(cbit.vcell.math.MembraneRegionEquation) PdeEquation(cbit.vcell.math.PdeEquation) Equation(cbit.vcell.math.Equation) FastRate(cbit.vcell.math.FastRate)

Example 3 with MembraneRegionEquation

use of cbit.vcell.math.MembraneRegionEquation in project vcell by virtualcell.

the class DiffEquMathMapping method refreshMathDescription.

/**
 * This method was created in VisualAge.
 */
@SuppressWarnings("deprecation")
private void refreshMathDescription() throws MappingException, MatrixException, MathException, ExpressionException, ModelException {
    // All sizes must be set for new ODE models and ratios must be set for old ones.
    simContext.checkValidity();
    // 
    // temporarily place all variables in a hashtable (before binding) and discarding duplicates (check for equality)
    // 
    VariableHash varHash = new VariableHash();
    StructureMapping[] structureMappings = simContext.getGeometryContext().getStructureMappings();
    // 
    // verify that all structures are mapped to subvolumes and all subvolumes are mapped to a structure
    // 
    // Structure structures[] =
    simContext.getGeometryContext().getModel().getStructures();
    // for (int i = 0; i < structures.length; i++){
    // StructureMapping sm = simContext.getGeometryContext().getStructureMapping(structures[i]);
    // if (sm==null || (sm.getGeometryClass() == null)){
    // localIssueList.add(new Issue(structures[i], IssueCategory.StructureNotMapped,"In Application '" + simContext.getName() + "', model structure '"+structures[i].getName()+"' not mapped to a geometry subdomain",Issue.SEVERITY_WARNING));
    // }
    // }
    // SubVolume subVolumes[] = simContext.getGeometryContext().getGeometry().getGeometrySpec().getSubVolumes();
    // for (int i = 0; i < subVolumes.length; i++){
    // Structure[] mappedStructures = simContext.getGeometryContext().getStructuresFromGeometryClass(subVolumes[i]);
    // if (mappedStructures==null || mappedStructures.length==0){
    // localIssueList.add(new Issue(subVolumes[i], IssueCategory.GeometryClassNotMapped,"In Application '" + simContext.getName() + "', geometry subVolume '"+subVolumes[i].getName()+"' not mapped from a model structure",Issue.SEVERITY_WARNING));
    // }
    // }
    // deals with model parameters
    HashMap<VolVariable, EventAssignmentOrRateRuleInitParameter> eventOrRateRuleVolVarHash = new HashMap<VolVariable, EventAssignmentOrRateRuleInitParameter>();
    HashMap<VolVariable, RateRuleRateParameter> rateRuleRateParamHash = new HashMap<VolVariable, RateRuleRateParameter>();
    ArrayList<SymbolTableEntry> rateRuleVarTargets = new ArrayList<SymbolTableEntry>();
    Model model = simContext.getModel();
    ModelUnitSystem modelUnitSystem = model.getUnitSystem();
    VCUnitDefinition timeUnit = modelUnitSystem.getTimeUnit();
    ModelParameter[] modelParameters = model.getModelParameters();
    if (simContext.getGeometry().getDimension() == 0) {
        // 
        // global parameters from model (that presently are constants)
        // 
        BioEvent[] bioEvents = simContext.getBioEvents();
        ArrayList<SymbolTableEntry> eventAssignTargets = new ArrayList<SymbolTableEntry>();
        if (bioEvents != null && bioEvents.length > 0) {
            for (BioEvent be : bioEvents) {
                ArrayList<EventAssignment> eventAssignments = be.getEventAssignments();
                if (eventAssignments != null) {
                    for (EventAssignment ea : eventAssignments) {
                        if (!eventAssignTargets.contains(ea.getTarget())) {
                            eventAssignTargets.add(ea.getTarget());
                        }
                    }
                }
            }
        }
        /**
         * @author anu : RATE RULES
         */
        RateRule[] rateRules = simContext.getRateRules();
        if (rateRules != null && rateRules.length > 0) {
            for (RateRule rr : rateRules) {
                SymbolTableEntry rateRuleVar = rr.getRateRuleVar();
                if (!rateRuleVarTargets.contains(rateRuleVar)) {
                    rateRuleVarTargets.add(rateRuleVar);
                }
            }
        }
        for (int j = 0; j < modelParameters.length; j++) {
            Expression modelParamExpr = modelParameters[j].getExpression();
            GeometryClass geometryClass = getDefaultGeometryClass(modelParamExpr);
            VCUnitDefinition paramUnit = modelParameters[j].getUnitDefinition();
            modelParamExpr = getIdentifierSubstitutions(modelParamExpr, paramUnit, geometryClass);
            if (eventAssignTargets.contains(modelParameters[j]) || rateRuleVarTargets.contains(modelParameters[j])) {
                EventAssignmentOrRateRuleInitParameter eap = null;
                try {
                    eap = addEventAssignmentOrRateRuleInitParameter(modelParameters[j], modelParamExpr, PARAMETER_ROLE_EVENTASSIGN_OR_RATERULE_INITCONDN, paramUnit);
                } catch (PropertyVetoException e) {
                    e.printStackTrace(System.out);
                    throw new MappingException(e.getMessage());
                }
                VolVariable volVar = new VolVariable(modelParameters[j].getName(), null);
                varHash.addVariable(volVar);
                eventOrRateRuleVolVarHash.put(volVar, eap);
                /**
                 * RATE RULES
                 */
                if (rateRuleVarTargets.contains(modelParameters[j])) {
                    RateRuleRateParameter rateParam = null;
                    try {
                        Expression origExp = simContext.getRateRule(modelParameters[j]).getRateRuleExpression();
                        VCUnitDefinition rateUnit = modelUnitSystem.getInstance_TBD();
                        if (paramUnit != null && !paramUnit.equals(modelUnitSystem.getInstance_TBD())) {
                            rateUnit = paramUnit.divideBy(timeUnit);
                        }
                        Expression rateExpr = getIdentifierSubstitutions(origExp, rateUnit, geometryClass);
                        rateParam = addRateRuleRateParameter(modelParameters[j], rateExpr, PARAMETER_ROLE_RATERULE_RATE, rateUnit);
                    } catch (PropertyVetoException e) {
                        e.printStackTrace(System.out);
                        throw new MappingException(e.getMessage());
                    }
                    rateRuleRateParamHash.put(volVar, rateParam);
                }
            } else {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(modelParameters[j], geometryClass), modelParamExpr, geometryClass));
            }
        }
    } else {
        for (int j = 0; j < modelParameters.length; j++) {
            Expression modelParamExpr = modelParameters[j].getExpression();
            GeometryClass geometryClass = getDefaultGeometryClass(modelParamExpr);
            modelParamExpr = getIdentifierSubstitutions(modelParamExpr, modelParameters[j].getUnitDefinition(), geometryClass);
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(modelParameters[j], geometryClass), modelParamExpr, geometryClass));
        }
    }
    // 
    for (SimulationContextParameter scParameter : simContext.getSimulationContextParameters()) {
        Expression scParameterExpression = scParameter.getExpression();
        GeometryClass gc = getDefaultGeometryClass(scParameterExpression);
        varHash.addVariable(newFunctionOrConstant(getMathSymbol(scParameter, gc), getIdentifierSubstitutions(scParameter.getExpression(), scParameter.getUnitDefinition(), gc), gc));
    }
    // 
    for (DataSymbol dataSymbol : simContext.getDataContext().getDataSymbols()) {
        if (dataSymbol instanceof FieldDataSymbol) {
            FieldDataSymbol fieldDataSymbol = (FieldDataSymbol) dataSymbol;
            GeometryClass geometryClass = null;
            FieldFunctionArguments ffs = new FieldFunctionArguments(fieldDataSymbol.getExternalDataIdentifier().getName(), fieldDataSymbol.getFieldDataVarName(), new Expression(fieldDataSymbol.getFieldDataVarTime()), VariableType.getVariableTypeFromVariableTypeName(fieldDataSymbol.getFieldDataVarType()));
            Expression exp = new Expression(ffs.infix());
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(dataSymbol, geometryClass), getIdentifierSubstitutions(exp, dataSymbol.getUnitDefinition(), geometryClass), geometryClass));
        } else {
            throw new RuntimeException("In Application '" + simContext.getName() + "', dataSymbol type '" + dataSymbol.getClass().getName() + "' not yet supported for math generation");
        }
    }
    // 
    // gather only those reactionSteps that are not "excluded"
    // 
    ReactionSpec[] reactionSpecs = simContext.getReactionContext().getReactionSpecs();
    Vector<ReactionStep> rsList = new Vector<ReactionStep>();
    for (int i = 0; i < reactionSpecs.length; i++) {
        if (reactionSpecs[i].isExcluded() == false) {
            rsList.add(reactionSpecs[i].getReactionStep());
        }
    }
    ReactionStep[] reactionSteps = new ReactionStep[rsList.size()];
    rsList.copyInto(reactionSteps);
    // 
    for (int i = 0; i < reactionSteps.length; i++) {
        Kinetics.UnresolvedParameter[] unresolvedParameters = reactionSteps[i].getKinetics().getUnresolvedParameters();
        if (unresolvedParameters != null && unresolvedParameters.length > 0) {
            StringBuffer buffer = new StringBuffer();
            for (int j = 0; j < unresolvedParameters.length; j++) {
                if (j > 0) {
                    buffer.append(", ");
                }
                buffer.append(unresolvedParameters[j].getName());
            }
            throw new MappingException("In Application '" + simContext.getName() + "', " + reactionSteps[i].getDisplayType() + " '" + reactionSteps[i].getName() + "' contains unresolved identifier(s): " + buffer);
        }
    }
    // 
    // create new MathDescription (based on simContext's previous MathDescription if possible)
    // 
    MathDescription oldMathDesc = simContext.getMathDescription();
    mathDesc = null;
    if (oldMathDesc != null) {
        if (oldMathDesc.getVersion() != null) {
            mathDesc = new MathDescription(oldMathDesc.getVersion());
        } else {
            mathDesc = new MathDescription(oldMathDesc.getName());
        }
    } else {
        mathDesc = new MathDescription(simContext.getName() + "_generated");
    }
    // 
    // volume variables
    // 
    Enumeration<SpeciesContextMapping> enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = enum1.nextElement();
        if (scm.getVariable() instanceof VolVariable) {
            if (!(mathDesc.getVariable(scm.getVariable().getName()) instanceof VolVariable)) {
                varHash.addVariable(scm.getVariable());
            }
        }
    }
    // 
    // membrane variables
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() instanceof MemVariable) {
            varHash.addVariable(scm.getVariable());
        }
    }
    // 
    // volume region variables
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() instanceof VolumeRegionVariable) {
            varHash.addVariable(scm.getVariable());
        }
    }
    // 
    // membrane region variables
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() instanceof MembraneRegionVariable) {
            varHash.addVariable(scm.getVariable());
        }
    }
    // 
    // add compartment and membrane subdomains
    // 
    ArrayList<CompartmentSubdomainContext> compartmentSubdomainContexts = new ArrayList<CompartmentSubdomainContext>();
    ArrayList<MembraneSubdomainContext> membraneSubdomainContexts = new ArrayList<MembraneSubdomainContext>();
    addSubdomains(model, compartmentSubdomainContexts, membraneSubdomainContexts);
    // membrane velocities set on MembraneSubdomains later.
    addSpatialProcesses(varHash, compartmentSubdomainContexts, membraneSubdomainContexts);
    varHash.addVariable(new Constant(getMathSymbol(model.getPI_CONSTANT(), null), getIdentifierSubstitutions(model.getPI_CONSTANT().getExpression(), model.getPI_CONSTANT().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getFARADAY_CONSTANT(), null), getIdentifierSubstitutions(model.getFARADAY_CONSTANT().getExpression(), model.getFARADAY_CONSTANT().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getFARADAY_CONSTANT_NMOLE(), null), getIdentifierSubstitutions(model.getFARADAY_CONSTANT_NMOLE().getExpression(), model.getFARADAY_CONSTANT_NMOLE().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getGAS_CONSTANT(), null), getIdentifierSubstitutions(model.getGAS_CONSTANT().getExpression(), model.getGAS_CONSTANT().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getTEMPERATURE(), null), getIdentifierSubstitutions(new Expression(simContext.getTemperatureKelvin()), model.getTEMPERATURE().getUnitDefinition(), null)));
    // 
    // only calculate potential if at least one MembraneMapping has CalculateVoltage == true
    // 
    boolean bCalculatePotential = false;
    for (int i = 0; i < structureMappings.length; i++) {
        if (structureMappings[i] instanceof MembraneMapping) {
            if (((MembraneMapping) structureMappings[i]).getCalculateVoltage()) {
                bCalculatePotential = true;
            }
        }
    }
    potentialMapping = new PotentialMapping(simContext, this);
    if (bCalculatePotential) {
        potentialMapping.computeMath();
        // 
        // copy functions for currents and constants for capacitances
        // 
        ElectricalDevice[] devices = potentialMapping.getElectricalDevices();
        for (int j = 0; j < devices.length; j++) {
            if (devices[j] instanceof MembraneElectricalDevice) {
                MembraneElectricalDevice membraneElectricalDevice = (MembraneElectricalDevice) devices[j];
                MembraneMapping memMapping = membraneElectricalDevice.getMembraneMapping();
                Parameter specificCapacitanceParm = memMapping.getParameterFromRole(MembraneMapping.ROLE_SpecificCapacitance);
                varHash.addVariable(new Constant(getMathSymbol(specificCapacitanceParm, memMapping.getGeometryClass()), getIdentifierSubstitutions(specificCapacitanceParm.getExpression(), specificCapacitanceParm.getUnitDefinition(), memMapping.getGeometryClass())));
                ElectricalDevice.ElectricalDeviceParameter transmembraneCurrentParm = membraneElectricalDevice.getParameterFromRole(ElectricalDevice.ROLE_TransmembraneCurrent);
                ElectricalDevice.ElectricalDeviceParameter totalCurrentParm = membraneElectricalDevice.getParameterFromRole(ElectricalDevice.ROLE_TotalCurrent);
                ElectricalDevice.ElectricalDeviceParameter capacitanceParm = membraneElectricalDevice.getParameterFromRole(ElectricalDevice.ROLE_Capacitance);
                GeometryClass geometryClass = membraneElectricalDevice.getMembraneMapping().getGeometryClass();
                if (totalCurrentParm != null && /* totalCurrentDensityParm.getExpression()!=null && */
                memMapping.getCalculateVoltage()) {
                    Expression totalCurrentDensityExp = (totalCurrentParm.getExpression() != null) ? (totalCurrentParm.getExpression()) : (new Expression(0.0));
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrentParm, geometryClass), getIdentifierSubstitutions(totalCurrentDensityExp, totalCurrentParm.getUnitDefinition(), geometryClass), geometryClass));
                }
                if (transmembraneCurrentParm != null && transmembraneCurrentParm.getExpression() != null && memMapping.getCalculateVoltage()) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(transmembraneCurrentParm, geometryClass), getIdentifierSubstitutions(transmembraneCurrentParm.getExpression(), transmembraneCurrentParm.getUnitDefinition(), geometryClass), geometryClass));
                }
                if (capacitanceParm != null && capacitanceParm.getExpression() != null && memMapping.getCalculateVoltage()) {
                    StructureMappingParameter sizeParameter = membraneElectricalDevice.getMembraneMapping().getSizeParameter();
                    if (simContext.getGeometry().getDimension() == 0 && (sizeParameter.getExpression() == null || sizeParameter.getExpression().isZero())) {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(capacitanceParm, geometryClass), getIdentifierSubstitutions(Expression.mult(memMapping.getNullSizeParameterValue(), specificCapacitanceParm.getExpression()), capacitanceParm.getUnitDefinition(), geometryClass), geometryClass));
                    } else {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(capacitanceParm, geometryClass), getIdentifierSubstitutions(capacitanceParm.getExpression(), capacitanceParm.getUnitDefinition(), geometryClass), geometryClass));
                    }
                }
                // 
                if (membraneElectricalDevice.getDependentVoltageExpression() == null) {
                    // is Voltage Independent?
                    StructureMapping.StructureMappingParameter initialVoltageParm = memMapping.getInitialVoltageParameter();
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(initialVoltageParm, memMapping.getGeometryClass()), getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), memMapping.getGeometryClass()), memMapping.getGeometryClass()));
                } else // 
                // membrane forced potential
                // 
                {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(memMapping.getMembrane().getMembraneVoltage(), memMapping.getGeometryClass()), getIdentifierSubstitutions(membraneElectricalDevice.getDependentVoltageExpression(), memMapping.getMembrane().getMembraneVoltage().getUnitDefinition(), memMapping.getGeometryClass()), memMapping.getGeometryClass()));
                }
            } else if (devices[j] instanceof CurrentClampElectricalDevice) {
                CurrentClampElectricalDevice currentClampDevice = (CurrentClampElectricalDevice) devices[j];
                // total current = current source (no capacitance)
                Parameter totalCurrentParm = currentClampDevice.getParameterFromRole(CurrentClampElectricalDevice.ROLE_TotalCurrent);
                Parameter currentParm = currentClampDevice.getParameterFromRole(CurrentClampElectricalDevice.ROLE_TransmembraneCurrent);
                // Parameter dependentVoltage = currentClampDevice.getCurrentClampStimulus().getVoltageParameter();
                Feature deviceElectrodeFeature = currentClampDevice.getCurrentClampStimulus().getElectrode().getFeature();
                Feature groundElectrodeFeature = simContext.getGroundElectrode().getFeature();
                Membrane membrane = model.getStructureTopology().getMembrane(deviceElectrodeFeature, groundElectrodeFeature);
                GeometryClass geometryClass = null;
                if (membrane != null) {
                    StructureMapping membraneStructureMapping = simContext.getGeometryContext().getStructureMapping(membrane);
                    geometryClass = membraneStructureMapping.getGeometryClass();
                }
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrentParm, geometryClass), getIdentifierSubstitutions(totalCurrentParm.getExpression(), totalCurrentParm.getUnitDefinition(), geometryClass), geometryClass));
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(currentParm, geometryClass), getIdentifierSubstitutions(currentParm.getExpression(), currentParm.getUnitDefinition(), geometryClass), geometryClass));
                // varHash.addVariable(newFunctionOrConstant(getMathSymbol(dependentVoltage,null),getIdentifierSubstitutions(currentClampDevice.getDependentVoltageExpression(),dependentVoltage.getUnitDefinition(),null)));
                // 
                // add user-defined parameters
                // 
                ElectricalDevice.ElectricalDeviceParameter[] parameters = currentClampDevice.getParameters();
                for (int k = 0; k < parameters.length; k++) {
                    if (parameters[k].getExpression() != null) {
                        // guards against voltage parameters that are "variable".
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameters[k], null), getIdentifierSubstitutions(parameters[k].getExpression(), parameters[k].getUnitDefinition(), geometryClass), geometryClass));
                    }
                }
            } else if (devices[j] instanceof VoltageClampElectricalDevice) {
                VoltageClampElectricalDevice voltageClampDevice = (VoltageClampElectricalDevice) devices[j];
                Feature deviceElectrodeFeature = voltageClampDevice.getVoltageClampStimulus().getElectrode().getFeature();
                Feature groundElectrodeFeature = simContext.getGroundElectrode().getFeature();
                Membrane membrane = model.getStructureTopology().getMembrane(deviceElectrodeFeature, groundElectrodeFeature);
                GeometryClass geometryClass = null;
                if (membrane != null) {
                    StructureMapping membraneStructureMapping = simContext.getGeometryContext().getStructureMapping(membrane);
                    geometryClass = membraneStructureMapping.getGeometryClass();
                }
                // total current = current source (no capacitance)
                Parameter totalCurrent = voltageClampDevice.getParameterFromRole(VoltageClampElectricalDevice.ROLE_TotalCurrent);
                Parameter totalCurrentParm = voltageClampDevice.getParameterFromRole(VoltageClampElectricalDevice.ROLE_TotalCurrent);
                Parameter voltageParm = voltageClampDevice.getParameterFromRole(VoltageClampElectricalDevice.ROLE_Voltage);
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrent, geometryClass), getIdentifierSubstitutions(totalCurrent.getExpression(), totalCurrent.getUnitDefinition(), geometryClass), geometryClass));
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrentParm, geometryClass), getIdentifierSubstitutions(totalCurrentParm.getExpression(), totalCurrentParm.getUnitDefinition(), geometryClass), geometryClass));
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(voltageParm, geometryClass), getIdentifierSubstitutions(voltageParm.getExpression(), voltageParm.getUnitDefinition(), geometryClass), geometryClass));
                // 
                // add user-defined parameters
                // 
                ElectricalDevice.ElectricalDeviceParameter[] parameters = voltageClampDevice.getParameters();
                for (int k = 0; k < parameters.length; k++) {
                    if (parameters[k].getRole() == ElectricalDevice.ROLE_UserDefined) {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameters[k], geometryClass), getIdentifierSubstitutions(parameters[k].getExpression(), parameters[k].getUnitDefinition(), geometryClass), geometryClass));
                    }
                }
            }
        }
    } else {
        // 
        for (int j = 0; j < structureMappings.length; j++) {
            if (structureMappings[j] instanceof MembraneMapping) {
                MembraneMapping memMapping = (MembraneMapping) structureMappings[j];
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(memMapping.getMembrane().getMembraneVoltage(), memMapping.getGeometryClass()), getIdentifierSubstitutions(memMapping.getInitialVoltageParameter().getExpression(), memMapping.getInitialVoltageParameter().getUnitDefinition(), memMapping.getGeometryClass()), memMapping.getGeometryClass()));
            }
        }
    }
    // 
    for (int j = 0; j < structureMappings.length; j++) {
        if (structureMappings[j] instanceof MembraneMapping) {
            MembraneMapping membraneMapping = (MembraneMapping) structureMappings[j];
            Membrane.MembraneVoltage membraneVoltage = membraneMapping.getMembrane().getMembraneVoltage();
            ElectricalDevice[] membraneDevices = potentialMapping.getElectricalDevices(membraneMapping.getMembrane());
            // ElectricalDevice membraneDevice = null;
            for (int i = 0; i < membraneDevices.length; i++) {
                if (membraneDevices[i].hasCapacitance() && membraneDevices[i].getDependentVoltageExpression() == null) {
                    GeometryClass geometryClass = membraneMapping.getGeometryClass();
                    if (geometryClass == null) {
                        throw new MappingException("Application '" + getSimulationContext().getName() + "'\nGeometry->StructureMapping->(" + structureMappings[j].getStructure().getTypeName() + ")'" + structureMappings[j].getStructure().getName() + "' must be mapped to geometry domain.\n(see 'Problems' tab)");
                    }
                    Domain domain = new Domain(geometryClass);
                    if (membraneMapping.getCalculateVoltage() && bCalculatePotential) {
                        if (geometryClass instanceof SurfaceClass) {
                            // 
                            if (mathDesc.getVariable(Membrane.MEMBRANE_VOLTAGE_REGION_NAME) == null) {
                                // varHash.addVariable(new MembraneRegionVariable(MembraneVoltage.MEMBRANE_VOLTAGE_REGION_NAME));
                                varHash.addVariable(new MembraneRegionVariable(getMathSymbol(membraneVoltage, geometryClass), domain));
                            }
                        } else {
                            // 
                            // spatially unresolved membrane, and must solve for potential ... make VolVariable for this compartment
                            // 
                            varHash.addVariable(new VolVariable(getMathSymbol(membraneVoltage, geometryClass), domain));
                        }
                        Parameter initialVoltageParm = membraneMapping.getInitialVoltageParameter();
                        Variable initVoltageFunction = newFunctionOrConstant(getMathSymbol(initialVoltageParm, geometryClass), getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), geometryClass), geometryClass);
                        varHash.addVariable(initVoltageFunction);
                    } else {
                        // 
                        // don't calculate voltage, still may need it though
                        // 
                        Parameter initialVoltageParm = membraneMapping.getInitialVoltageParameter();
                        Variable voltageFunction = newFunctionOrConstant(getMathSymbol(membraneMapping.getMembrane().getMembraneVoltage(), geometryClass), getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), geometryClass), geometryClass);
                        varHash.addVariable(voltageFunction);
                    }
                }
            }
        }
    }
    // 
    for (int j = 0; j < reactionSteps.length; j++) {
        ReactionStep rs = reactionSteps[j];
        if (simContext.getReactionContext().getReactionSpec(rs).isExcluded()) {
            continue;
        }
        Kinetics.KineticsParameter[] parameters = rs.getKinetics().getKineticsParameters();
        GeometryClass geometryClass = null;
        if (rs.getStructure() != null) {
            geometryClass = simContext.getGeometryContext().getStructureMapping(rs.getStructure()).getGeometryClass();
        }
        if (parameters != null) {
            for (int i = 0; i < parameters.length; i++) {
                if (((parameters[i].getRole() == Kinetics.ROLE_CurrentDensity) || (parameters[i].getRole() == Kinetics.ROLE_LumpedCurrent)) && (parameters[i].getExpression() == null || parameters[i].getExpression().isZero())) {
                    continue;
                }
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameters[i], geometryClass), getIdentifierSubstitutions(parameters[i].getExpression(), parameters[i].getUnitDefinition(), geometryClass), geometryClass));
            }
        }
    }
    // 
    // initial constants (either function or constant)
    // 
    SpeciesContextSpec[] speciesContextSpecs = simContext.getReactionContext().getSpeciesContextSpecs();
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        // add initial count if present (!= null)
        SpeciesContextSpecParameter initCountParm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_InitialCount);
        SpeciesContext speciesContext = speciesContextSpecs[i].getSpeciesContext();
        if (initCountParm != null && initCountParm.getExpression() != null) {
            Expression initCountExpr = new Expression(initCountParm.getExpression());
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContext.getStructure());
            String[] symbols = initCountExpr.getSymbols();
            // Check if 'initExpr' has other speciesContexts in its expression, need to replace it with 'spContext_init'
            for (int j = 0; symbols != null && j < symbols.length; j++) {
                // if symbol is a speciesContext, replacing it with a reference to initial condition for that speciesContext.
                SpeciesContext spC = null;
                SymbolTableEntry ste = initCountExpr.getSymbolBinding(symbols[j]);
                if (ste instanceof SpeciesContextSpecProxyParameter) {
                    SpeciesContextSpecProxyParameter spspp = (SpeciesContextSpecProxyParameter) ste;
                    if (spspp.getTarget() instanceof SpeciesContext) {
                        spC = (SpeciesContext) spspp.getTarget();
                        SpeciesContextSpec spcspec = simContext.getReactionContext().getSpeciesContextSpec(spC);
                        SpeciesContextSpecParameter spCInitParm = spcspec.getParameterFromRole(SpeciesContextSpec.ROLE_InitialCount);
                        // need to get init condn expression, but can't get it from getMathSymbol() (mapping between bio and math), hence get it as below.
                        Expression scsInitExpr = new Expression(spCInitParm, getNameScope());
                        // scsInitExpr.bindExpression(this);
                        initCountExpr.substituteInPlace(new Expression(spC.getName()), scsInitExpr);
                    }
                }
            }
            // now create the appropriate function for the current speciesContextSpec.
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(initCountParm, sm.getGeometryClass()), getIdentifierSubstitutions(initCountExpr, initCountParm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        // add initial concentration (may be derived from initial count if necessary)
        SpeciesContextSpecParameter initConcParm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration);
        if (initConcParm != null) {
            Expression initConcExpr = null;
            if (initConcParm.getExpression() != null) {
                initConcExpr = new Expression(initConcParm.getExpression());
            } else if (initCountParm != null && initCountParm.getExpression() != null) {
                Expression structureSizeExpr = new Expression(speciesContext.getStructure().getStructureSize(), getNameScope());
                VCUnitDefinition concUnit = initConcParm.getUnitDefinition();
                VCUnitDefinition countDensityUnit = initCountParm.getUnitDefinition().divideBy(speciesContext.getStructure().getStructureSize().getUnitDefinition());
                Expression unitFactor = getUnitFactor(concUnit.divideBy(countDensityUnit));
                initConcExpr = Expression.mult(Expression.div(new Expression(initCountParm, getNameScope()), structureSizeExpr), unitFactor);
            }
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContext.getStructure());
            String[] symbols = initConcExpr.getSymbols();
            // Check if 'initExpr' has other speciesContexts in its expression, need to replace it with 'spContext_init'
            for (int j = 0; symbols != null && j < symbols.length; j++) {
                // if symbol is a speciesContext, replacing it with a reference to initial condition for that speciesContext.
                SpeciesContext spC = null;
                SymbolTableEntry ste = initConcExpr.getSymbolBinding(symbols[j]);
                if (ste instanceof SpeciesContextSpecProxyParameter) {
                    SpeciesContextSpecProxyParameter spspp = (SpeciesContextSpecProxyParameter) ste;
                    if (spspp.getTarget() instanceof SpeciesContext) {
                        spC = (SpeciesContext) spspp.getTarget();
                        SpeciesContextSpec spcspec = simContext.getReactionContext().getSpeciesContextSpec(spC);
                        SpeciesContextSpecParameter spCInitParm = spcspec.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration);
                        // if initConc param expression is null, try initCount
                        if (spCInitParm.getExpression() == null) {
                            spCInitParm = spcspec.getParameterFromRole(SpeciesContextSpec.ROLE_InitialCount);
                        }
                        // need to get init condn expression, but can't get it from getMathSymbol() (mapping between bio and math), hence get it as below.
                        Expression scsInitExpr = new Expression(spCInitParm, getNameScope());
                        // scsInitExpr.bindExpression(this);
                        initConcExpr.substituteInPlace(new Expression(spC.getName()), scsInitExpr);
                    }
                }
            }
            // now create the appropriate function for the current speciesContextSpec.
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(initConcParm, sm.getGeometryClass()), getIdentifierSubstitutions(initConcExpr, initConcParm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextMapping scm = getSpeciesContextMapping(speciesContextSpecs[i].getSpeciesContext());
        SpeciesContextSpec.SpeciesContextSpecParameter diffParm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_DiffusionRate);
        if (diffParm != null && (scm.isPDERequired())) {
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(diffParm, sm.getGeometryClass()), getIdentifierSubstitutions(diffParm.getExpression(), diffParm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpec.SpeciesContextSpecParameter bc_xm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueXm);
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
        if (bc_xm != null && (bc_xm.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_xm, sm.getGeometryClass()), getIdentifierSubstitutions(bc_xm.getExpression(), bc_xm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_xp = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueXp);
        if (bc_xp != null && (bc_xp.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_xp, sm.getGeometryClass()), getIdentifierSubstitutions(bc_xp.getExpression(), bc_xp.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_ym = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueYm);
        if (bc_ym != null && (bc_ym.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_ym, sm.getGeometryClass()), getIdentifierSubstitutions(bc_ym.getExpression(), bc_ym.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_yp = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueYp);
        if (bc_yp != null && (bc_yp.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_yp, sm.getGeometryClass()), getIdentifierSubstitutions(bc_yp.getExpression(), bc_yp.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_zm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueZm);
        if (bc_zm != null && (bc_zm.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_zm, sm.getGeometryClass()), getIdentifierSubstitutions(bc_zm.getExpression(), bc_zm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_zp = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueZp);
        if (bc_zp != null && (bc_zp.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_zp, sm.getGeometryClass()), getIdentifierSubstitutions(bc_zp.getExpression(), bc_zp.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velX = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityX);
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
        GeometryClass geometryClass = sm.getGeometryClass();
        if (advection_velX != null && (advection_velX.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velX, geometryClass), getIdentifierSubstitutions(advection_velX.getExpression(), advection_velX.getUnitDefinition(), geometryClass), geometryClass));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velY = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityY);
        if (advection_velY != null && (advection_velY.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velY, geometryClass), getIdentifierSubstitutions(advection_velY.getExpression(), advection_velY.getUnitDefinition(), geometryClass), geometryClass));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velZ = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityZ);
        if (advection_velZ != null && (advection_velZ.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velZ, geometryClass), getIdentifierSubstitutions(advection_velZ.getExpression(), advection_velZ.getUnitDefinition(), geometryClass), geometryClass));
        }
    }
    // 
    // constant species (either function or constant)
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() instanceof Constant) {
            varHash.addVariable(scm.getVariable());
        }
    }
    // 
    // conversion factors
    // 
    varHash.addVariable(new Constant(model.getKMOLE().getName(), getIdentifierSubstitutions(model.getKMOLE().getExpression(), model.getKMOLE().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(model.getN_PMOLE().getName(), getIdentifierSubstitutions(model.getN_PMOLE().getExpression(), model.getN_PMOLE().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(model.getKMILLIVOLTS().getName(), getIdentifierSubstitutions(model.getKMILLIVOLTS().getExpression(), model.getKMILLIVOLTS().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(model.getK_GHK().getName(), getIdentifierSubstitutions(model.getK_GHK().getExpression(), model.getK_GHK().getUnitDefinition(), null)));
    // 
    for (int i = 0; i < structureMappings.length; i++) {
        StructureMapping sm = structureMappings[i];
        if (simContext.getGeometry().getDimension() == 0) {
            StructureMappingParameter sizeParm = sm.getSizeParameter();
            if (sizeParm != null && sizeParm.getExpression() != null) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(sizeParm, sm.getGeometryClass()), getIdentifierSubstitutions(sizeParm.getExpression(), sizeParm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
            } else {
                if (sm instanceof MembraneMapping) {
                    MembraneMapping mm = (MembraneMapping) sm;
                    StructureMappingParameter volFrac = mm.getVolumeFractionParameter();
                    if (volFrac != null && volFrac.getExpression() != null) {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(volFrac, sm.getGeometryClass()), getIdentifierSubstitutions(volFrac.getExpression(), volFrac.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
                    }
                    StructureMappingParameter surfToVol = mm.getSurfaceToVolumeParameter();
                    if (surfToVol != null && surfToVol.getExpression() != null) {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(surfToVol, sm.getGeometryClass()), getIdentifierSubstitutions(surfToVol.getExpression(), surfToVol.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
                    }
                }
            }
        } else {
            Parameter parm = sm.getParameterFromRole(StructureMapping.ROLE_AreaPerUnitArea);
            if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SurfaceClass) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm.getGeometryClass()), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
            }
            parm = sm.getParameterFromRole(StructureMapping.ROLE_AreaPerUnitVolume);
            if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm.getGeometryClass()), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
            }
            parm = sm.getParameterFromRole(StructureMapping.ROLE_VolumePerUnitArea);
            if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SurfaceClass) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm.getGeometryClass()), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
            }
            parm = sm.getParameterFromRole(StructureMapping.ROLE_VolumePerUnitVolume);
            if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm.getGeometryClass()), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
            }
        }
        StructureMappingParameter sizeParm = sm.getSizeParameter();
        if (sm.getGeometryClass() != null && sizeParm != null) {
            if (simContext.getGeometry().getDimension() == 0) {
                if (sizeParm.getExpression() != null) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(sizeParm, sm.getGeometryClass()), getIdentifierSubstitutions(sizeParm.getExpression(), sizeParm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
                }
            } else {
                String compartmentName = sm.getGeometryClass().getName();
                VCUnitDefinition sizeUnit = sm.getSizeParameter().getUnitDefinition();
                String sizeFunctionName = null;
                if (sm instanceof MembraneMapping) {
                    MembraneMapping mm = (MembraneMapping) sm;
                    if (mm.getGeometryClass() instanceof SurfaceClass) {
                        sizeFunctionName = MathFunctionDefinitions.Function_regionArea_current.getFunctionName();
                    } else if (mm.getGeometryClass() instanceof SubVolume) {
                        sizeFunctionName = MathFunctionDefinitions.Function_regionVolume_current.getFunctionName();
                    }
                } else if (sm instanceof FeatureMapping) {
                    sizeFunctionName = MathFunctionDefinitions.Function_regionVolume_current.getFunctionName();
                } else {
                    throw new RuntimeException("structure mapping " + sm.getClass().getName() + " not yet supported");
                }
                Expression totalVolumeCorrection = sm.getStructureSizeCorrection(simContext, this);
                Expression sizeFunctionExpression = Expression.function(sizeFunctionName, new Expression[] { new Expression("'" + compartmentName + "'") });
                // sizeFunctionExpression.bindExpression(mathDesc);
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(sizeParm, sm.getGeometryClass()), getIdentifierSubstitutions(Expression.mult(totalVolumeCorrection, sizeFunctionExpression), sizeUnit, sm.getGeometryClass()), sm.getGeometryClass()));
            }
        }
    }
    // 
    for (SymbolTableEntry rrvSTE : rateRuleVarTargets) {
        if (rrvSTE instanceof SpeciesContext) {
            SpeciesContext rateRuleSpContext = (SpeciesContext) rrvSTE;
            // check if speciesContext has already been added as a vol/membrane var
            SpeciesContextMapping scm = getSpeciesContextMapping(rateRuleSpContext);
            if (scm.getVariable() instanceof VolVariable || scm.getVariable() instanceof MemVariable) {
                throw new RuntimeException("SpeciesContext '" + rrvSTE.getName() + "' has an equation and is also a rate rule variable, which is not allowed.");
            }
            // get the initial condition expression of the speciesContext.
            SpeciesContextSpec speciesContextSpec = simContext.getReactionContext().getSpeciesContextSpec(rateRuleSpContext);
            SpeciesContextSpecParameter scsInitParam = speciesContextSpec.getInitialConditionParameter();
            Expression scInitExpr = scsInitParam.getExpression();
            GeometryClass geometryClass = getDefaultGeometryClass(scInitExpr);
            VCUnitDefinition scsInitParamUnit = scsInitParam.getUnitDefinition();
            scInitExpr = getIdentifierSubstitutions(scInitExpr, scsInitParamUnit, geometryClass);
            EventAssignmentOrRateRuleInitParameter eap = null;
            try {
                // create an eventAssgnmentOrRateRuleInitParameter for the rate rule variable
                eap = addEventAssignmentOrRateRuleInitParameter(rateRuleSpContext, scInitExpr, PARAMETER_ROLE_EVENTASSIGN_OR_RATERULE_INITCONDN, scsInitParamUnit);
            } catch (PropertyVetoException e) {
                e.printStackTrace(System.out);
                throw new MappingException(e.getMessage());
            }
            // create a volVariable for this speciesContext (shouldn't have one already - since a speciesContext that has a rate rule should not participate in a reaction.
            VolVariable volVar = new VolVariable(rateRuleSpContext.getName(), null);
            varHash.addVariable(volVar);
            eventOrRateRuleVolVarHash.put(volVar, eap);
            // create the rate parameter
            RateRuleRateParameter rateParam = null;
            try {
                Expression origExp = simContext.getRateRule(rateRuleSpContext).getRateRuleExpression();
                VCUnitDefinition rateUnit = modelUnitSystem.getInstance_TBD();
                if (scsInitParamUnit != null && !scsInitParamUnit.equals(modelUnitSystem.getInstance_TBD())) {
                    rateUnit = scsInitParamUnit.divideBy(timeUnit);
                }
                Expression rateExpr = getIdentifierSubstitutions(origExp, rateUnit, geometryClass);
                rateParam = addRateRuleRateParameter(rateRuleSpContext, rateExpr, PARAMETER_ROLE_RATERULE_RATE, rateUnit);
            } catch (PropertyVetoException e) {
                e.printStackTrace(System.out);
                throw new MappingException(e.getMessage());
            }
            rateRuleRateParamHash.put(volVar, rateParam);
        }
    // end if (ste instanceof SC)
    }
    // 
    for (int i = 0; i < fieldMathMappingParameters.length; i++) {
        GeometryClass geometryClass = fieldMathMappingParameters[i].getGeometryClass();
        varHash.addVariable(newFunctionOrConstant(getMathSymbol(fieldMathMappingParameters[i], geometryClass), getIdentifierSubstitutions(fieldMathMappingParameters[i].getExpression(), fieldMathMappingParameters[i].getUnitDefinition(), geometryClass), fieldMathMappingParameters[i].getGeometryClass()));
    }
    // 
    // functions
    // 
    enum1 = getSpeciesContextMappings();
    RateRule[] rateRules = simContext.getRateRules();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() == null && scm.getDependencyExpression() != null) {
            // check if speciesContext has a rateRule; then the speciesContext should not be added as a constant
            if (rateRules == null) {
                if (simContext.getRateRule(scm.getSpeciesContext()) == null) {
                    StructureMapping sm = simContext.getGeometryContext().getStructureMapping(scm.getSpeciesContext().getStructure());
                    if (sm.getGeometryClass() == null) {
                        Structure s = sm.getStructure();
                        if (s != null) {
                            throw new RuntimeException("unmapped structure " + s.getName());
                        }
                        throw new RuntimeException("structure mapping with no structure or mapping");
                    }
                    Variable dependentVariable = newFunctionOrConstant(getMathSymbol(scm.getSpeciesContext(), sm.getGeometryClass()), getIdentifierSubstitutions(scm.getDependencyExpression(), scm.getSpeciesContext().getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass());
                    dependentVariable.setDomain(new Domain(sm.getGeometryClass()));
                    varHash.addVariable(dependentVariable);
                }
            }
        }
    }
    BioEvent[] bioevents = simContext.getBioEvents();
    if (bioevents != null && bioevents.length > 0) {
        for (BioEvent be : bioevents) {
            // transform the bioEvent trigger/delay to math Event
            for (LocalParameter p : be.getEventParameters()) {
                if (p.getExpression() != null) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(p, null), getIdentifierSubstitutions(p.getExpression(), p.getUnitDefinition(), null), null));
                } else if (be.getParameter(BioEventParameterType.GeneralTriggerFunction) == p) {
                    // 
                    // use generated function here.
                    // 
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(p, null), getIdentifierSubstitutions(be.generateTriggerExpression(), p.getUnitDefinition(), null), null));
                }
            }
        }
    }
    // 
    // set Variables to MathDescription all at once with the order resolved by "VariableHash"
    // 
    mathDesc.setAllVariables(varHash.getAlphabeticallyOrderedVariables());
    // 
    if (simContext.getGeometryContext().getGeometry() != null) {
        try {
            mathDesc.setGeometry(simContext.getGeometryContext().getGeometry());
        } catch (java.beans.PropertyVetoException e) {
            e.printStackTrace(System.out);
            throw new MappingException("failure setting geometry " + e.getMessage());
        }
    } else {
        throw new MappingException("geometry must be defined");
    }
    // 
    for (CompartmentSubdomainContext compartmentSubDomainContext : compartmentSubdomainContexts) {
        SubVolume subVolume = compartmentSubDomainContext.subvolume;
        CompartmentSubDomain subDomain = mathDesc.getCompartmentSubDomain(subVolume.getName());
        // 
        // assign boundary condition types
        // 
        StructureMapping[] mappedSMs = simContext.getGeometryContext().getStructureMappings(subVolume);
        FeatureMapping mappedFM = null;
        for (int i = 0; i < mappedSMs.length; i++) {
            if (mappedSMs[i] instanceof FeatureMapping) {
                if (mappedFM != null) {
                    lg.warn("WARNING:::: MathMapping.refreshMathDescription() ... assigning boundary condition types not unique");
                }
                mappedFM = (FeatureMapping) mappedSMs[i];
            }
        }
        if (mappedFM != null) {
            if (simContext.getGeometry().getDimension() > 0) {
                subDomain.setBoundaryConditionXm(mappedFM.getBoundaryConditionTypeXm());
                subDomain.setBoundaryConditionXp(mappedFM.getBoundaryConditionTypeXp());
            }
            if (simContext.getGeometry().getDimension() > 1) {
                subDomain.setBoundaryConditionYm(mappedFM.getBoundaryConditionTypeYm());
                subDomain.setBoundaryConditionYp(mappedFM.getBoundaryConditionTypeYp());
            }
            if (simContext.getGeometry().getDimension() > 2) {
                subDomain.setBoundaryConditionZm(mappedFM.getBoundaryConditionTypeZm());
                subDomain.setBoundaryConditionZp(mappedFM.getBoundaryConditionTypeZp());
            }
        }
        // 
        // create equations
        // 
        VolumeStructureAnalyzer structureAnalyzer = getVolumeStructureAnalyzer(subVolume);
        Enumeration<SpeciesContextMapping> enumSCM = getSpeciesContextMappings();
        while (enumSCM.hasMoreElements()) {
            SpeciesContextMapping scm = enumSCM.nextElement();
            SpeciesContext sc = scm.getSpeciesContext();
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(sc.getStructure());
            SpeciesContextSpec scs = simContext.getReactionContext().getSpeciesContextSpec(sc);
            // 
            // if an independent volume variable, then create equation for it (if mapped to this subDomain)
            // 
            final GeometryClass gc = sm.getGeometryClass();
            if (gc == null || !gc.getName().equals(subDomain.getName())) {
                continue;
            }
            SpeciesContextSpecParameter initConcParameter = scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration);
            if ((scm.getVariable() instanceof VolumeRegionVariable) && scm.getDependencyExpression() == null) {
                VolumeRegionVariable volumeRegionVariable = (VolumeRegionVariable) scm.getVariable();
                Expression initial = getIdentifierSubstitutions(new Expression(initConcParameter, getNameScope()), initConcParameter.getUnitDefinition(), sm.getGeometryClass());
                Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()).getGeometryClass());
                VolumeRegionEquation volumeRegionEquation = new VolumeRegionEquation(volumeRegionVariable, initial);
                volumeRegionEquation.setVolumeRateExpression(rate);
                subDomain.addEquation(volumeRegionEquation);
            } else if (scm.getVariable() instanceof VolVariable && scm.getDependencyExpression() == null) {
                VolVariable variable = (VolVariable) scm.getVariable();
                Equation equation = null;
                if (sm.getGeometryClass() == subVolume) {
                    if (scm.isPDERequired()) {
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = getIdentifierSubstitutions(new Expression(initConcParameter, getNameScope()), initConcParameter.getUnitDefinition(), sm.getGeometryClass());
                        Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()).getGeometryClass());
                        SpeciesContextSpecParameter diffusionParameter = scs.getDiffusionParameter();
                        Expression diffusion = getIdentifierSubstitutions(new Expression(diffusionParameter, getNameScope()), diffusionParameter.getUnitDefinition(), sm.getGeometryClass());
                        equation = new PdeEquation(variable, initial, rate, diffusion);
                        ((PdeEquation) equation).setBoundaryXm((scs.getBoundaryXmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXmParameter(), sm.getGeometryClass())));
                        ((PdeEquation) equation).setBoundaryXp((scs.getBoundaryXpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXpParameter(), sm.getGeometryClass())));
                        ((PdeEquation) equation).setBoundaryYm((scs.getBoundaryYmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYmParameter(), sm.getGeometryClass())));
                        ((PdeEquation) equation).setBoundaryYp((scs.getBoundaryYpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYpParameter(), sm.getGeometryClass())));
                        ((PdeEquation) equation).setBoundaryZm((scs.getBoundaryZmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZmParameter(), sm.getGeometryClass())));
                        ((PdeEquation) equation).setBoundaryZp((scs.getBoundaryZpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZpParameter(), sm.getGeometryClass())));
                        if (simContext.getGeometry().getDimension() >= 1) {
                            Expression velXExp = null;
                            if (scs.getVelocityXParameter().getExpression() != null) {
                                velXExp = new Expression(getMathSymbol(scs.getVelocityXParameter(), sm.getGeometryClass()));
                            } else {
                                SpatialQuantity[] velX_quantities = scs.getVelocityQuantities(QuantityComponent.X);
                                if (velX_quantities.length > 0) {
                                    int numRegions = simContext.getGeometry().getGeometrySurfaceDescription().getGeometricRegions(subVolume).length;
                                    if (velX_quantities.length == 1 && numRegions == 1) {
                                        velXExp = new Expression(getMathSymbol(velX_quantities[0], sm.getGeometryClass()));
                                    } else {
                                        throw new MappingException("multiple advection velocities enabled set for multiple volume domains ");
                                    }
                                }
                            }
                            ((PdeEquation) equation).setVelocityX(velXExp);
                        }
                        if (simContext.getGeometry().getDimension() >= 2) {
                            Expression velYExp = null;
                            if (scs.getVelocityYParameter().getExpression() != null) {
                                velYExp = new Expression(getMathSymbol(scs.getVelocityYParameter(), sm.getGeometryClass()));
                            } else {
                                SpatialQuantity[] velY_quantities = scs.getVelocityQuantities(QuantityComponent.Y);
                                if (velY_quantities.length > 0) {
                                    int numRegions = simContext.getGeometry().getGeometrySurfaceDescription().getGeometricRegions(subVolume).length;
                                    if (velY_quantities.length == 1 && numRegions == 1) {
                                        velYExp = new Expression(getMathSymbol(velY_quantities[0], sm.getGeometryClass()));
                                    } else {
                                        throw new MappingException("multiple advection velocities enabled set for multiple volume domains ");
                                    }
                                }
                            }
                            ((PdeEquation) equation).setVelocityY(velYExp);
                        }
                        if (simContext.getGeometry().getDimension() == 3) {
                            Expression velZExp = null;
                            if (scs.getVelocityZParameter().getExpression() != null) {
                                velZExp = new Expression(getMathSymbol(scs.getVelocityZParameter(), sm.getGeometryClass()));
                            } else {
                                SpatialQuantity[] velZ_quantities = scs.getVelocityQuantities(QuantityComponent.Z);
                                if (velZ_quantities.length > 0) {
                                    int numRegions = simContext.getGeometry().getGeometrySurfaceDescription().getGeometricRegions(subVolume).length;
                                    if (velZ_quantities.length == 1 && numRegions == 1) {
                                        velZExp = new Expression(getMathSymbol(velZ_quantities[0], sm.getGeometryClass()));
                                    } else {
                                        throw new MappingException("multiple advection velocities enabled set for multiple volume domains ");
                                    }
                                }
                            }
                            ((PdeEquation) equation).setVelocityZ(velZExp);
                        }
                        subDomain.replaceEquation(equation);
                    } else {
                        // 
                        // ODE - species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(initConcParameter, null));
                        Expression rate = (scm.getRate() == null) ? new Expression(0.0) : getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()).getGeometryClass());
                        equation = new OdeEquation(variable, initial, rate);
                        subDomain.replaceEquation(equation);
                    }
                }
            }
        }
        // 
        // create fast system (if neccessary)
        // 
        SpeciesContextMapping[] fastSpeciesContextMappings = structureAnalyzer.getFastSpeciesContextMappings();
        if (fastSpeciesContextMappings != null) {
            FastSystem fastSystem = new FastSystem(mathDesc);
            for (int i = 0; i < fastSpeciesContextMappings.length; i++) {
                SpeciesContextMapping scm = fastSpeciesContextMappings[i];
                if (scm.getFastInvariant() == null) {
                    // 
                    // independant-fast variable, create a fastRate object
                    // 
                    Expression rate = getIdentifierSubstitutions(scm.getFastRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), subVolume);
                    FastRate fastRate = new FastRate(rate);
                    fastSystem.addFastRate(fastRate);
                } else {
                    // 
                    // dependant-fast variable, create a fastInvariant object
                    // 
                    Expression rate = getIdentifierSubstitutions(scm.getFastInvariant(), modelUnitSystem.getVolumeConcentrationUnit(), subVolume);
                    FastInvariant fastInvariant = new FastInvariant(rate);
                    fastSystem.addFastInvariant(fastInvariant);
                }
            }
            subDomain.setFastSystem(fastSystem);
            // constructor calls the 'refresh' method which constructs depemdency matrix, dependent/independent vars and pseudoconstants, etc.
            // FastSystemAnalyzer fs_analyzer =
            new FastSystemAnalyzer(fastSystem, mathDesc);
        }
        // 
        // create ode's for voltages to be calculated on unresolved membranes mapped to this subVolume
        // 
        Structure[] localStructures = simContext.getGeometryContext().getStructuresFromGeometryClass(subVolume);
        for (int sIndex = 0; sIndex < localStructures.length; sIndex++) {
            if (localStructures[sIndex] instanceof Membrane) {
                Membrane membrane = (Membrane) localStructures[sIndex];
                MembraneMapping membraneMapping = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(membrane);
                if ((membraneMapping.getGeometryClass() instanceof SubVolume) && membraneMapping.getCalculateVoltage()) {
                    MembraneElectricalDevice capacitiveDevice = potentialMapping.getCapacitiveDevice(membrane);
                    if (capacitiveDevice.getDependentVoltageExpression() == null) {
                        VolVariable vVar = (VolVariable) mathDesc.getVariable(getMathSymbol(capacitiveDevice.getVoltageSymbol(), membraneMapping.getGeometryClass()));
                        Expression initExp = new Expression(getMathSymbol(capacitiveDevice.getMembraneMapping().getInitialVoltageParameter(), membraneMapping.getGeometryClass()));
                        subDomain.addEquation(new OdeEquation(vVar, initExp, getIdentifierSubstitutions(potentialMapping.getOdeRHS(capacitiveDevice, this), membrane.getMembraneVoltage().getUnitDefinition().divideBy(timeUnit), membraneMapping.getGeometryClass())));
                    } else {
                    // 
                    // 
                    // 
                    }
                }
            }
        }
    }
    // 
    for (MembraneSubdomainContext memSubdomainContext : membraneSubdomainContexts) {
        MembraneSubDomain memSubDomain = memSubdomainContext.membraneSubdomain;
        SurfaceClass surfaceClass = memSubdomainContext.surfaceClass;
        for (SurfaceRegionObject surfaceRegionObject : memSubdomainContext.surfaceRegionObjects) {
            if (surfaceRegionObject.isQuantityCategoryEnabled(QuantityCategory.SurfaceVelocity)) {
                int dim = simContext.getGeometry().getDimension();
                if (dim != 2) {
                    throw new MappingException("Membrane Velocity only supported for 2D geometries");
                }
                if (simContext.getGeometry().getDimension() >= 1) {
                    SpatialQuantity velXQuantity = surfaceRegionObject.getSpatialQuantity(QuantityCategory.SurfaceVelocity, QuantityComponent.X);
                    Expression velXExp = new Expression(velXQuantity, simContext.getNameScope());
                    memSubDomain.setVelocityX(getIdentifierSubstitutions(velXExp, velXQuantity.getUnitDefinition(), surfaceClass));
                }
                if (simContext.getGeometry().getDimension() >= 2) {
                    SpatialQuantity velYQuantity = surfaceRegionObject.getSpatialQuantity(QuantityCategory.SurfaceVelocity, QuantityComponent.Y);
                    Expression velYExp = new Expression(velYQuantity, simContext.getNameScope());
                    memSubDomain.setVelocityY(getIdentifierSubstitutions(velYExp, velYQuantity.getUnitDefinition(), surfaceClass));
                }
                if (simContext.getGeometry().getDimension() == 3) {
                    SpatialQuantity velZQuantity = surfaceRegionObject.getSpatialQuantity(QuantityCategory.SurfaceVelocity, QuantityComponent.Z);
                    Expression velZExp = new Expression(velZQuantity, simContext.getNameScope());
                    // memSubDomain.setVelocityZ(getIdentifierSubstitutions(velZExp, velZQuantity.getUnitDefinition(), surfaceClass));
                    throw new MappingException("Membrane Velocity not supported for 2D problems");
                }
            }
        }
        // 
        // create equations for membrane-bound molecular species
        // 
        MembraneStructureAnalyzer membraneStructureAnalyzer = getMembraneStructureAnalyzer(surfaceClass);
        Enumeration<SpeciesContextMapping> enumSCM = getSpeciesContextMappings();
        while (enumSCM.hasMoreElements()) {
            SpeciesContextMapping scm = enumSCM.nextElement();
            SpeciesContext sc = scm.getSpeciesContext();
            SpeciesContextSpec scs = simContext.getReactionContext().getSpeciesContextSpec(sc);
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(sc.getStructure());
            // 
            if ((scm.getVariable() instanceof MembraneRegionVariable) && scm.getDependencyExpression() == null) {
                MembraneRegionEquation equation = null;
                MembraneRegionVariable memRegionVar = (MembraneRegionVariable) scm.getVariable();
                if (sm.getGeometryClass() == surfaceClass) {
                    // 
                    // species context belongs to this subDomain
                    // 
                    Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), sm.getGeometryClass()));
                    Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()).getGeometryClass());
                    equation = new MembraneRegionEquation(memRegionVar, initial);
                    equation.setMembraneRateExpression(rate);
                    // equation.setUniformRateExpression(newUniformRateExpression);
                    memSubDomain.replaceEquation(equation);
                }
            } else if ((scm.getVariable() instanceof MemVariable) && scm.getDependencyExpression() == null) {
                // 
                if (sm.getGeometryClass() == surfaceClass) {
                    Equation equation = null;
                    MemVariable variable = (MemVariable) scm.getVariable();
                    if (scm.isPDERequired()) {
                        // 
                        // PDE
                        // 
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), sm.getGeometryClass()));
                        Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()).getGeometryClass());
                        Expression diffusion = new Expression(getMathSymbol(scs.getDiffusionParameter(), sm.getGeometryClass()));
                        equation = new PdeEquation(variable, initial, rate, diffusion);
                        ((PdeEquation) equation).setBoundaryXm((scs.getBoundaryXmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXmParameter(), sm.getGeometryClass())));
                        ((PdeEquation) equation).setBoundaryXp((scs.getBoundaryXpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXpParameter(), sm.getGeometryClass())));
                        ((PdeEquation) equation).setBoundaryYm((scs.getBoundaryYmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYmParameter(), sm.getGeometryClass())));
                        ((PdeEquation) equation).setBoundaryYp((scs.getBoundaryYpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYpParameter(), sm.getGeometryClass())));
                        ((PdeEquation) equation).setBoundaryZm((scs.getBoundaryZmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZmParameter(), sm.getGeometryClass())));
                        ((PdeEquation) equation).setBoundaryZp((scs.getBoundaryZpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZpParameter(), sm.getGeometryClass())));
                        memSubDomain.replaceEquation(equation);
                    } else {
                        // 
                        // ODE
                        // 
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), null));
                        Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()).getGeometryClass());
                        equation = new OdeEquation(variable, initial, rate);
                        memSubDomain.replaceEquation(equation);
                    }
                }
            }
        }
        Enumeration<SpeciesContextMapping> enum_scm = getSpeciesContextMappings();
        while (enum_scm.hasMoreElements()) {
            SpeciesContextMapping scm = enum_scm.nextElement();
            if (scm.isPDERequired() || scm.getVariable() instanceof VolumeRegionVariable) {
                // Species species = scm.getSpeciesContext().getSpecies();
                Variable var = scm.getVariable();
                final Domain dm = var.getDomain();
                if (dm != null) {
                    final String domainName = dm.getName();
                    if (sameName(domainName, memSubDomain.getInsideCompartment()) || sameName(domainName, memSubDomain.getOutsideCompartment())) {
                        JumpCondition jc = memSubDomain.getJumpCondition(var);
                        if (jc == null) {
                            // System.out.println("MathMapping.refreshMathDescription(), adding jump condition for diffusing variable "+var.getName()+" on membrane "+membraneStructureAnalyzer.getMembrane().getName());
                            if (var instanceof VolVariable) {
                                jc = new JumpCondition((VolVariable) var);
                            } else if (var instanceof VolumeRegionVariable) {
                                jc = new JumpCondition((VolumeRegionVariable) var);
                            } else {
                                throw new RuntimeException("unexpected Variable type " + var.getClass().getName());
                            }
                            memSubDomain.addJumpCondition(jc);
                        }
                    }
                }
            }
        }
        // 
        // set jump conditions for any volume variables or volume region variables that have explicitly defined fluxes
        // 
        ResolvedFlux[] resolvedFluxes = membraneStructureAnalyzer.getResolvedFluxes();
        if (resolvedFluxes != null) {
            for (int i = 0; i < resolvedFluxes.length; i++) {
                SpeciesContext sc = resolvedFluxes[i].getSpeciesContext();
                SpeciesContextMapping scm = getSpeciesContextMapping(sc);
                StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(sc.getStructure());
                if (scm.getVariable() instanceof VolVariable && scm.isPDERequired()) {
                    VolVariable volVar = (VolVariable) scm.getVariable();
                    JumpCondition jc = memSubDomain.getJumpCondition(volVar);
                    if (jc == null) {
                        jc = new JumpCondition(volVar);
                        memSubDomain.addJumpCondition(jc);
                    }
                    Expression flux = getIdentifierSubstitutions(resolvedFluxes[i].getFluxExpression(), resolvedFluxes[i].getUnitDefinition(), membraneStructureAnalyzer.getSurfaceClass());
                    if (memSubDomain.getInsideCompartment().getName().equals(sm.getGeometryClass().getName())) {
                        jc.setInFlux(flux);
                    } else if (memSubDomain.getOutsideCompartment().getName().equals(sm.getGeometryClass().getName())) {
                        jc.setOutFlux(flux);
                    } else {
                        throw new RuntimeException("Application  " + simContext.getName() + " : " + scm.getSpeciesContext().getName() + " has spatially resolved flux at membrane " + scm.getSpeciesContext().getStructure().getName() + " with a non-local flux species " + scm.getSpeciesContext().getName());
                    }
                } else if (scm.getVariable() instanceof VolumeRegionVariable) {
                    VolumeRegionVariable volRegionVar = (VolumeRegionVariable) scm.getVariable();
                    JumpCondition jc = memSubDomain.getJumpCondition(volRegionVar);
                    if (jc == null) {
                        jc = new JumpCondition(volRegionVar);
                        memSubDomain.addJumpCondition(jc);
                    }
                    Expression flux = getIdentifierSubstitutions(resolvedFluxes[i].getFluxExpression(), resolvedFluxes[i].getUnitDefinition(), membraneStructureAnalyzer.getSurfaceClass());
                    if (memSubDomain.getInsideCompartment().getName().equals(sm.getGeometryClass().getName())) {
                        jc.setInFlux(flux);
                    } else if (memSubDomain.getOutsideCompartment().getName().equals(sm.getGeometryClass().getName())) {
                        jc.setOutFlux(flux);
                    } else {
                        throw new RuntimeException("Application  " + simContext.getName() + " : " + scm.getSpeciesContext().getName() + " has spatially resolved flux at membrane " + scm.getSpeciesContext().getStructure().getName() + " with a non-local flux species " + scm.getSpeciesContext().getName());
                    }
                } else {
                    throw new MappingException("Application  " + simContext.getName() + " : " + scm.getSpeciesContext().getName() + " has spatially resolved flux at membrane " + scm.getSpeciesContext().getStructure().getName() + ", but doesn't diffuse in compartment " + scm.getSpeciesContext().getStructure().getName());
                }
            }
        }
        // 
        // create fast system (if neccessary)
        // 
        SpeciesContextMapping[] fastSpeciesContextMappings = membraneStructureAnalyzer.getFastSpeciesContextMappings();
        if (fastSpeciesContextMappings != null) {
            FastSystem fastSystem = new FastSystem(mathDesc);
            for (int i = 0; i < fastSpeciesContextMappings.length; i++) {
                SpeciesContextMapping scm = fastSpeciesContextMappings[i];
                if (scm.getFastInvariant() == null) {
                    // 
                    // independant-fast variable, create a fastRate object
                    // 
                    VCUnitDefinition rateUnit = scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit);
                    FastRate fastRate = new FastRate(getIdentifierSubstitutions(scm.getFastRate(), rateUnit, surfaceClass));
                    fastSystem.addFastRate(fastRate);
                } else {
                    // 
                    // dependant-fast variable, create a fastInvariant object
                    // 
                    VCUnitDefinition invariantUnit = scm.getSpeciesContext().getUnitDefinition();
                    FastInvariant fastInvariant = new FastInvariant(getIdentifierSubstitutions(scm.getFastInvariant(), invariantUnit, surfaceClass));
                    fastSystem.addFastInvariant(fastInvariant);
                }
            }
            memSubDomain.setFastSystem(fastSystem);
            // constructor calls the 'refresh' method which constructs depemdency matrix, dependent/independent vars and pseudoconstants, etc.
            // FastSystemAnalyzer fs_analyzer =
            new FastSystemAnalyzer(fastSystem, mathDesc);
        }
        // 
        // create Membrane-region equations for potential of this resolved membrane
        // 
        Structure[] resolvedSurfaceStructures = membraneStructureAnalyzer.getStructures();
        for (int m = 0; m < resolvedSurfaceStructures.length; m++) {
            if (resolvedSurfaceStructures[m] instanceof Membrane) {
                Membrane membrane = (Membrane) resolvedSurfaceStructures[m];
                MembraneMapping membraneMapping = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(membrane);
                if (membraneMapping.getCalculateVoltage()) {
                    ElectricalDevice[] membraneDevices = potentialMapping.getElectricalDevices(membrane);
                    int numCapacitiveDevices = 0;
                    MembraneElectricalDevice capacitiveDevice = null;
                    for (int i = 0; i < membraneDevices.length; i++) {
                        if (membraneDevices[i] instanceof MembraneElectricalDevice) {
                            numCapacitiveDevices++;
                            capacitiveDevice = (MembraneElectricalDevice) membraneDevices[i];
                        }
                    }
                    if (numCapacitiveDevices != 1) {
                        throw new MappingException("expecting 1 capacitive electrical device on graph edge for membrane " + membrane.getName() + ", found '" + numCapacitiveDevices + "'");
                    }
                    if (mathDesc.getVariable(getMathSymbol(capacitiveDevice.getVoltageSymbol(), membraneMapping.getGeometryClass())) instanceof MembraneRegionVariable) {
                        MembraneRegionVariable vVar = (MembraneRegionVariable) mathDesc.getVariable(getMathSymbol(capacitiveDevice.getVoltageSymbol(), membraneMapping.getGeometryClass()));
                        Parameter initialVoltageParm = capacitiveDevice.getMembraneMapping().getInitialVoltageParameter();
                        Expression initExp = getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), capacitiveDevice.getMembraneMapping().getGeometryClass());
                        MembraneRegionEquation vEquation = new MembraneRegionEquation(vVar, initExp);
                        vEquation.setMembraneRateExpression(getIdentifierSubstitutions(potentialMapping.getOdeRHS(capacitiveDevice, this), membrane.getMembraneVoltage().getUnitDefinition().divideBy(timeUnit), capacitiveDevice.getMembraneMapping().getGeometryClass()));
                        memSubDomain.addEquation(vEquation);
                    }
                }
            }
        }
    }
    // create equations for event assignment or rate rule targets that are model params/species, etc.
    Set<VolVariable> hashKeySet = eventOrRateRuleVolVarHash.keySet();
    Iterator<VolVariable> volVarsIter = hashKeySet.iterator();
    // working under the assumption that we are dealing with non-spatial math, hence only one compartment domain!
    SubDomain subDomain = mathDesc.getSubDomains().nextElement();
    while (volVarsIter.hasNext()) {
        VolVariable volVar = volVarsIter.next();
        EventAssignmentOrRateRuleInitParameter initParam = eventOrRateRuleVolVarHash.get(volVar);
        // check event initial condition, it shouldn't contain vars, we have to do it here, coz we want to substitute functions...etc.
        Expression eapExp = MathUtilities.substituteFunctions(initParam.getExpression(), mathDesc);
        if (eapExp.getSymbols() != null) {
            for (String symbol : eapExp.getSymbols()) {
                SymbolTableEntry ste = eapExp.getSymbolBinding(symbol);
                if (ste instanceof VolVariable || ste instanceof MemVariable) {
                    throw new MathException("Variables are not allowed in Event assignment initial condition.\nEvent assignment target: " + volVar.getName() + " has variable (" + symbol + ") in its expression.");
                }
            }
        }
        Expression rateExpr = new Expression(0.0);
        RateRuleRateParameter rateParam = rateRuleRateParamHash.get(volVar);
        if (rateParam != null) {
            // this is a rate rule, get its expression.
            rateExpr = new Expression(getMathSymbol(rateParam, null));
        }
        Equation equation = new OdeEquation(volVar, new Expression(getMathSymbol(initParam, null)), rateExpr);
        subDomain.addEquation(equation);
    }
    // events - add events to math desc for event assignments that have parameters as target variables
    if (bioevents != null && bioevents.length > 0) {
        for (BioEvent be : bioevents) {
            // transform the bioEvent trigger/delay to math Event
            LocalParameter genTriggerParam = be.getParameter(BioEventParameterType.GeneralTriggerFunction);
            Expression mathTriggerExpr = getIdentifierSubstitutions(new Expression(genTriggerParam, be.getNameScope()), modelUnitSystem.getInstance_DIMENSIONLESS(), null);
            Delay mathDelay = null;
            LocalParameter delayParam = be.getParameter(BioEventParameterType.TriggerDelay);
            if (delayParam != null && delayParam.getExpression() != null && !delayParam.getExpression().compareEqual(new Expression(0.0))) {
                boolean bUseValsFromTriggerTime = be.getUseValuesFromTriggerTime();
                Expression mathDelayExpr = getIdentifierSubstitutions(new Expression(delayParam, be.getNameScope()), timeUnit, null);
                mathDelay = new Delay(bUseValsFromTriggerTime, mathDelayExpr);
            }
            // now deal with (bio)event Assignment translation to math EventAssignment
            ArrayList<EventAssignment> eventAssignments = be.getEventAssignments();
            ArrayList<Event.EventAssignment> mathEventAssignmentsList = new ArrayList<Event.EventAssignment>();
            if (eventAssignments != null) {
                for (EventAssignment ea : eventAssignments) {
                    SymbolTableEntry ste = simContext.getEntry(ea.getTarget().getName());
                    if (ste instanceof StructureSize) {
                        throw new RuntimeException("Event Assignment Variable for compartment size is not supported yet");
                    }
                    VCUnitDefinition eventAssignVarUnit = ste.getUnitDefinition();
                    Variable variable = varHash.getVariable(ste.getName());
                    Event.EventAssignment mathEA = new Event.EventAssignment(variable, getIdentifierSubstitutions(ea.getAssignmentExpression(), eventAssignVarUnit, null));
                    mathEventAssignmentsList.add(mathEA);
                }
            }
            // use the translated trigger, delay and event assignments to create (math) event
            Event mathEvent = new Event(be.getName(), mathTriggerExpr, mathDelay, mathEventAssignmentsList);
            mathDesc.addEvent(mathEvent);
        }
    }
    if (simContext.getMicroscopeMeasurement() != null && simContext.getMicroscopeMeasurement().getFluorescentSpecies().size() > 0) {
        MicroscopeMeasurement measurement = simContext.getMicroscopeMeasurement();
        Expression volumeConcExp = new Expression(0.0);
        Expression membraneDensityExp = new Expression(0.0);
        for (SpeciesContext speciesContext : measurement.getFluorescentSpecies()) {
            GeometryClass geometryClass = simContext.getGeometryContext().getStructureMapping(speciesContext.getStructure()).getGeometryClass();
            StructureMapping structureMapping = simContext.getGeometryContext().getStructureMapping(speciesContext.getStructure());
            StructureMappingParameter unitSizeParameter = structureMapping.getUnitSizeParameter();
            Expression mappedSpeciesContextExpression = Expression.mult(unitSizeParameter.getExpression(), new Expression(getMathSymbol(speciesContext, geometryClass)));
            VCUnitDefinition mappedSpeciesContextUnit = unitSizeParameter.getUnitDefinition().multiplyBy(speciesContext.getUnitDefinition());
            if (geometryClass instanceof SubVolume) {
                // volume function
                int dimension = 3;
                VCUnitDefinition desiredConcUnits = model.getUnitSystem().getInstance("molecules").divideBy(model.getUnitSystem().getLengthUnit().raiseTo(new ucar.units_vcell.RationalNumber(dimension)));
                Expression unitFactor = getUnitFactor(desiredConcUnits.divideBy(mappedSpeciesContextUnit));
                volumeConcExp = Expression.add(volumeConcExp, Expression.mult(unitFactor, mappedSpeciesContextExpression)).flatten();
            } else if (geometryClass instanceof SurfaceClass) {
                // membrane function
                int dimension = 2;
                VCUnitDefinition desiredSurfaceDensityUnits = model.getUnitSystem().getInstance("molecules").divideBy(model.getUnitSystem().getLengthUnit().raiseTo(new ucar.units_vcell.RationalNumber(dimension)));
                Expression unitFactor = getUnitFactor(desiredSurfaceDensityUnits.divideBy(mappedSpeciesContextUnit));
                membraneDensityExp = Expression.add(membraneDensityExp, Expression.mult(unitFactor, mappedSpeciesContextExpression)).flatten();
            } else {
                throw new MathException("unsupported geometry mapping for microscopy measurement");
            }
        }
        ConvolutionKernel kernel = measurement.getConvolutionKernel();
        if (kernel instanceof ExperimentalPSF) {
            if (!membraneDensityExp.isZero()) {
                throw new MappingException("membrane variables and functions not yet supported for Z projection in Microcopy Measurements");
            }
            ExperimentalPSF psf = (ExperimentalPSF) kernel;
            DataSymbol psfDataSymbol = psf.getPSFDataSymbol();
            if (psfDataSymbol instanceof FieldDataSymbol) {
                FieldDataSymbol fieldDataSymbol = (FieldDataSymbol) psfDataSymbol;
                String fieldDataName = ((FieldDataSymbol) psfDataSymbol).getExternalDataIdentifier().getName();
                Expression psfExp = Expression.function(FieldFunctionDefinition.FUNCTION_name, new Expression("'" + fieldDataName + "'"), new Expression("'" + fieldDataSymbol.getFieldDataVarName() + "'"), new Expression(fieldDataSymbol.getFieldDataVarTime()), new Expression("'" + fieldDataSymbol.getFieldDataVarType() + "'"));
                varHash.addVariable(new Function("__PSF__", psfExp, null));
            }
            Expression convExp = Expression.function(ConvFunctionDefinition.FUNCTION_name, volumeConcExp, new Expression("__PSF__"));
            varHash.addVariable(newFunctionOrConstant(measurement.getName(), convExp, null));
        } else if (kernel instanceof GaussianConvolutionKernel) {
            GaussianConvolutionKernel gaussianConvolutionKernel = (GaussianConvolutionKernel) kernel;
            GaussianConvolutionDataGeneratorKernel mathKernel = new GaussianConvolutionDataGeneratorKernel(gaussianConvolutionKernel.getSigmaXY_um(), gaussianConvolutionKernel.getSigmaZ_um());
            ConvolutionDataGenerator dataGenerator = new ConvolutionDataGenerator(measurement.getName(), mathKernel, volumeConcExp, membraneDensityExp);
            mathDesc.getPostProcessingBlock().addDataGenerator(dataGenerator);
        } else if (kernel instanceof ProjectionZKernel) {
            if (mathDesc.getGeometry().getDimension() == 3) {
                if (!membraneDensityExp.isZero()) {
                    throw new MappingException("membrane variables and functions not yet supported for Z projection in Microcopy Measurements");
                }
                ProjectionDataGenerator dataGenerator = new ProjectionDataGenerator(measurement.getName(), null, ProjectionDataGenerator.Axis.z, ProjectionDataGenerator.Operation.sum, volumeConcExp);
                mathDesc.getPostProcessingBlock().addDataGenerator(dataGenerator);
            } else {
                throw new MappingException("Z Projection is only supported in 3D spatial applications.");
            }
        }
    }
    // 
    for (int i = 0; i < fieldMathMappingParameters.length; i++) {
        if (fieldMathMappingParameters[i] instanceof UnitFactorParameter) {
            GeometryClass geometryClass = fieldMathMappingParameters[i].getGeometryClass();
            Variable variable = newFunctionOrConstant(getMathSymbol(fieldMathMappingParameters[i], geometryClass), getIdentifierSubstitutions(fieldMathMappingParameters[i].getExpression(), fieldMathMappingParameters[i].getUnitDefinition(), geometryClass), fieldMathMappingParameters[i].getGeometryClass());
            if (mathDesc.getVariable(variable.getName()) == null) {
                mathDesc.addVariable(variable);
            }
        }
    }
    if (!mathDesc.isValid()) {
        System.out.println(mathDesc.getVCML_database());
        throw new MappingException("generated an invalid mathDescription: " + mathDesc.getWarning());
    }
// System.out.println("]]]]]]]]]]]]]]]]]]]]]] VCML string begin ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
// System.out.println(mathDesc.getVCML());
// System.out.println("]]]]]]]]]]]]]]]]]]]]]] VCML string end ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
}
Also used : MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) ArrayList(java.util.ArrayList) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) SpeciesContext(cbit.vcell.model.SpeciesContext) Feature(cbit.vcell.model.Feature) MemVariable(cbit.vcell.math.MemVariable) SubVolume(cbit.vcell.geometry.SubVolume) Vector(java.util.Vector) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) FastInvariant(cbit.vcell.math.FastInvariant) GaussianConvolutionKernel(cbit.vcell.mapping.MicroscopeMeasurement.GaussianConvolutionKernel) PropertyVetoException(java.beans.PropertyVetoException) FieldDataSymbol(cbit.vcell.data.FieldDataSymbol) DataSymbol(cbit.vcell.data.DataSymbol) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) FastSystem(cbit.vcell.math.FastSystem) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) ReactionStep(cbit.vcell.model.ReactionStep) MembraneRegionEquation(cbit.vcell.math.MembraneRegionEquation) SurfaceClass(cbit.vcell.geometry.SurfaceClass) VariableHash(cbit.vcell.math.VariableHash) ExperimentalPSF(cbit.vcell.mapping.MicroscopeMeasurement.ExperimentalPSF) ConvolutionDataGenerator(cbit.vcell.math.ConvolutionDataGenerator) GaussianConvolutionDataGeneratorKernel(cbit.vcell.math.ConvolutionDataGenerator.GaussianConvolutionDataGeneratorKernel) Structure(cbit.vcell.model.Structure) ModelUnitSystem(cbit.vcell.model.ModelUnitSystem) LocalParameter(cbit.vcell.mapping.ParameterContext.LocalParameter) VoltageClampElectricalDevice(cbit.vcell.mapping.potential.VoltageClampElectricalDevice) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Expression(cbit.vcell.parser.Expression) Model(cbit.vcell.model.Model) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Parameter(cbit.vcell.model.Parameter) SpeciesContextSpecProxyParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecProxyParameter) SimulationContextParameter(cbit.vcell.mapping.SimulationContext.SimulationContextParameter) ModelParameter(cbit.vcell.model.Model.ModelParameter) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) LocalParameter(cbit.vcell.mapping.ParameterContext.LocalParameter) Event(cbit.vcell.math.Event) ProjectionDataGenerator(cbit.vcell.math.ProjectionDataGenerator) SurfaceRegionObject(cbit.vcell.mapping.spatial.SurfaceRegionObject) FieldDataSymbol(cbit.vcell.data.FieldDataSymbol) MembraneRegionVariable(cbit.vcell.math.MembraneRegionVariable) HashMap(java.util.HashMap) MathDescription(cbit.vcell.math.MathDescription) MembraneElectricalDevice(cbit.vcell.mapping.potential.MembraneElectricalDevice) Delay(cbit.vcell.math.Event.Delay) PropertyVetoException(java.beans.PropertyVetoException) PdeEquation(cbit.vcell.math.PdeEquation) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubDomain(cbit.vcell.math.SubDomain) PointSubDomain(cbit.vcell.math.PointSubDomain) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) CurrentClampElectricalDevice(cbit.vcell.mapping.potential.CurrentClampElectricalDevice) SpatialQuantity(cbit.vcell.mapping.spatial.SpatialObject.SpatialQuantity) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) EventAssignment(cbit.vcell.mapping.BioEvent.EventAssignment) CurrentClampElectricalDevice(cbit.vcell.mapping.potential.CurrentClampElectricalDevice) MembraneElectricalDevice(cbit.vcell.mapping.potential.MembraneElectricalDevice) ElectricalDevice(cbit.vcell.mapping.potential.ElectricalDevice) VoltageClampElectricalDevice(cbit.vcell.mapping.potential.VoltageClampElectricalDevice) VolVariable(cbit.vcell.math.VolVariable) StructureSize(cbit.vcell.model.Structure.StructureSize) ProjectionZKernel(cbit.vcell.mapping.MicroscopeMeasurement.ProjectionZKernel) ModelParameter(cbit.vcell.model.Model.ModelParameter) OdeEquation(cbit.vcell.math.OdeEquation) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubDomain(cbit.vcell.math.SubDomain) PointSubDomain(cbit.vcell.math.PointSubDomain) Domain(cbit.vcell.math.Variable.Domain) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) JumpCondition(cbit.vcell.math.JumpCondition) GeometryClass(cbit.vcell.geometry.GeometryClass) VolVariable(cbit.vcell.math.VolVariable) MembraneRegionVariable(cbit.vcell.math.MembraneRegionVariable) PointVariable(cbit.vcell.math.PointVariable) VolumeRegionVariable(cbit.vcell.math.VolumeRegionVariable) MemVariable(cbit.vcell.math.MemVariable) Variable(cbit.vcell.math.Variable) SpeciesContextSpecProxyParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecProxyParameter) Constant(cbit.vcell.math.Constant) VolumeRegionVariable(cbit.vcell.math.VolumeRegionVariable) Function(cbit.vcell.math.Function) SymbolTableEntry(cbit.vcell.parser.SymbolTableEntry) Membrane(cbit.vcell.model.Membrane) VolumeRegionEquation(cbit.vcell.math.VolumeRegionEquation) PotentialMapping(cbit.vcell.mapping.potential.PotentialMapping) EventAssignment(cbit.vcell.mapping.BioEvent.EventAssignment) FieldFunctionArguments(cbit.vcell.field.FieldFunctionArguments) PdeEquation(cbit.vcell.math.PdeEquation) ComputeMembraneMetricEquation(cbit.vcell.math.ComputeMembraneMetricEquation) VolumeRegionEquation(cbit.vcell.math.VolumeRegionEquation) OdeEquation(cbit.vcell.math.OdeEquation) MembraneRegionEquation(cbit.vcell.math.MembraneRegionEquation) Equation(cbit.vcell.math.Equation) FastRate(cbit.vcell.math.FastRate) SimulationContextParameter(cbit.vcell.mapping.SimulationContext.SimulationContextParameter) ConvolutionKernel(cbit.vcell.mapping.MicroscopeMeasurement.ConvolutionKernel) GaussianConvolutionKernel(cbit.vcell.mapping.MicroscopeMeasurement.GaussianConvolutionKernel) MathException(cbit.vcell.math.MathException)

Example 4 with MembraneRegionEquation

use of cbit.vcell.math.MembraneRegionEquation in project vcell by virtualcell.

the class MathDescriptionCellRenderer method getTreeCellRendererComponent.

/**
 * Insert the method's description here.
 * Creation date: (7/27/2000 6:41:57 PM)
 * @return java.awt.Component
 */
public java.awt.Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
    JLabel component = (JLabel) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
    boolean bLoaded = false;
    // 
    try {
        if (value instanceof BioModelNode) {
            BioModelNode node = (BioModelNode) value;
            if (node.getUserObject() instanceof PdeEquation) {
                PdeEquation pdeEquation = (PdeEquation) node.getUserObject();
                Variable var = pdeEquation.getVariable();
                component.setToolTipText("PDE Equation");
                // \u2207 = nabla ... del operator
                // \u2219 = dot
                String DEL = "\u2207";
                // "\u2202";     //  '\u2202' is partial differentiation    'd' is regular diff
                String PARTIAL_DIFF = "d";
                String Super2 = "\u00b2";
                String DOT = "\u2219";
                // String diffusionTerm = DEL+" "+DOT+" "+"("+pdeEquation.getDiffusionExpression()+" "+DEL+" "+var.getName()+")";
                String diffusionTerm = "";
                if (pdeEquation.getVelocityX() != null || pdeEquation.getVelocityY() != null || pdeEquation.getVelocityZ() != null) {
                    if (pdeEquation.getDiffusionExpression().isZero()) {
                        // reaction/advection
                        diffusionTerm = "- " + DEL + " " + DOT + "( velocity " + var.getName() + " )";
                    } else {
                        // reaction/diffusion/advection
                        diffusionTerm = DEL + " " + DOT + " (" + pdeEquation.getDiffusionExpression().infix() + " " + DEL + "  " + var.getName() + "   -   velocity " + var.getName() + ")";
                    }
                } else {
                    diffusionTerm = "(" + pdeEquation.getDiffusionExpression().infix() + ") " + DEL + Super2 + " " + var.getName();
                }
                String gradTerm = "";
                if (pdeEquation.getGradientX() != null && !pdeEquation.getGradientX().isZero()) {
                    gradTerm += " + " + PARTIAL_DIFF + "[" + pdeEquation.getGradientX().infix() + "]/" + PARTIAL_DIFF + "x";
                }
                if (pdeEquation.getGradientY() != null && !pdeEquation.getGradientY().isZero()) {
                    gradTerm += " + " + PARTIAL_DIFF + "[" + pdeEquation.getGradientY().infix() + "]/" + PARTIAL_DIFF + "y";
                }
                if (pdeEquation.getGradientZ() != null && !pdeEquation.getGradientZ().isZero()) {
                    gradTerm += " + " + PARTIAL_DIFF + "[" + pdeEquation.getGradientZ().infix() + "]/" + PARTIAL_DIFF + "z";
                }
                String sourceTerm = pdeEquation.getRateExpression().infix();
                if (!sourceTerm.equals("0.0")) {
                    component.setText(PARTIAL_DIFF + "[" + var.getName() + "]/" + PARTIAL_DIFF + "t = " + diffusionTerm + gradTerm + " + " + sourceTerm);
                } else {
                    component.setText(PARTIAL_DIFF + "[" + var.getName() + "]/" + PARTIAL_DIFF + "t = " + diffusionTerm + gradTerm);
                }
            } else if (node.getUserObject() instanceof OdeEquation) {
                OdeEquation odeEquation = (OdeEquation) node.getUserObject();
                Variable var = odeEquation.getVariable();
                component.setToolTipText("ODE Equation");
                component.setText("d[" + var.getName() + "]/dt = " + odeEquation.getRateExpression().infix());
            } else if (node.getUserObject() instanceof MembraneRegionEquation) {
                MembraneRegionEquation membraneRegionEquation = (MembraneRegionEquation) node.getUserObject();
                Variable var = membraneRegionEquation.getVariable();
                component.setToolTipText("Membrane Region Equation");
                component.setText("Membrane Region Equation for " + var.getName());
            } else if (node.getUserObject() instanceof JumpCondition) {
                JumpCondition jumpCondition = (JumpCondition) node.getUserObject();
                Variable var = jumpCondition.getVariable();
                component.setToolTipText("Jump Condition");
                component.setText("Flux for " + var.getName());
            } else if (node.getUserObject() instanceof Constant) {
                Constant constant = (Constant) node.getUserObject();
                component.setToolTipText("Constant");
                component.setText(constant.getName() + " = " + constant.getExpression().infix());
            } else if (node.getUserObject() instanceof Function) {
                Function function = (Function) node.getUserObject();
                component.setToolTipText("Function");
                component.setText(function.getName() + " = " + function.getExpression().infix());
            } else if (node.getUserObject() instanceof SubDomain) {
                SubDomain subDomain = (SubDomain) node.getUserObject();
                component.setToolTipText("SubDomain");
                component.setText(subDomain.getName());
            } else if (node.getUserObject() instanceof FastSystem) {
                component.setToolTipText("Fast System");
                component.setText("Fast System");
            } else if (node.getUserObject() instanceof FastInvariant) {
                FastInvariant fi = (FastInvariant) node.getUserObject();
                component.setToolTipText("Fast Invariant");
                component.setText("fast invariant: " + fi.getFunction().infix());
            } else if (node.getUserObject() instanceof FastRate) {
                FastRate fr = (FastRate) node.getUserObject();
                component.setToolTipText("Fast Rate");
                component.setText("fast rate: " + fr.getFunction().infix());
            } else if (node.getUserObject() instanceof Annotation) {
                Annotation annotation = (Annotation) node.getUserObject();
                component.setToolTipText("Annotation");
                component.setText("\"" + annotation + "\"");
            } else {
            }
            if (selectedFont == null && component.getFont() != null) {
                selectedFont = component.getFont().deriveFont(Font.BOLD);
            }
            if (unselectedFont == null && component.getFont() != null) {
                unselectedFont = component.getFont().deriveFont(Font.PLAIN);
            }
            if (bLoaded) {
                component.setFont(selectedFont);
            } else {
                component.setFont(unselectedFont);
            }
        }
    } catch (Throwable e) {
        e.printStackTrace(System.out);
    }
    // 
    return component;
}
Also used : JumpCondition(cbit.vcell.math.JumpCondition) Variable(cbit.vcell.math.Variable) Constant(cbit.vcell.math.Constant) JLabel(javax.swing.JLabel) FastRate(cbit.vcell.math.FastRate) BioModelNode(cbit.vcell.desktop.BioModelNode) FastInvariant(cbit.vcell.math.FastInvariant) Annotation(cbit.vcell.desktop.Annotation) PdeEquation(cbit.vcell.math.PdeEquation) SubDomain(cbit.vcell.math.SubDomain) Function(cbit.vcell.math.Function) OdeEquation(cbit.vcell.math.OdeEquation) FastSystem(cbit.vcell.math.FastSystem) MembraneRegionEquation(cbit.vcell.math.MembraneRegionEquation)

Example 5 with MembraneRegionEquation

use of cbit.vcell.math.MembraneRegionEquation in project vcell by virtualcell.

the class ModelOptimizationSpec method fromMath.

/**
 * Insert the method's description here.
 * Creation date: (11/1/2005 8:11:32 PM)
 * @return cbit.vcell.mapping.MathSystemHash
 * @param mathDesc cbit.vcell.math.MathDescription
 */
private static MathSystemHash fromMath(cbit.vcell.math.MathDescription mathDesc) {
    MathSystemHash hash = new MathSystemHash();
    hash.addSymbol(new MathSystemHash.IndependentVariable("t"));
    hash.addSymbol(new MathSystemHash.IndependentVariable("x"));
    hash.addSymbol(new MathSystemHash.IndependentVariable("y"));
    hash.addSymbol(new MathSystemHash.IndependentVariable("z"));
    Variable[] vars = (Variable[]) BeanUtils.getArray(mathDesc.getVariables(), Variable.class);
    for (int i = 0; i < vars.length; i++) {
        hash.addSymbol(new MathSystemHash.Variable(vars[i].getName(), vars[i].getExpression()));
    }
    SubDomain[] subDomains = (SubDomain[]) BeanUtils.getArray(mathDesc.getSubDomains(), SubDomain.class);
    for (int i = 0; i < subDomains.length; i++) {
        Equation[] equations = (Equation[]) BeanUtils.getArray(subDomains[i].getEquations(), Equation.class);
        for (int j = 0; j < equations.length; j++) {
            MathSystemHash.Variable var = (MathSystemHash.Variable) hash.getSymbol(equations[j].getVariable().getName());
            hash.addSymbol(new MathSystemHash.VariableInitial(var, equations[j].getInitialExpression()));
            if (equations[j] instanceof PdeEquation) {
                // hash.addSymbol(new MathSystemHash.VariableDerivative(var,pde.getRateExpression()));
                throw new RuntimeException("MathSystemHash doesn't yet support spatial models");
            } else if (equations[j] instanceof VolumeRegionEquation) {
                // hash.addSymbol(new MathSystemHash.VariableDerivative(var,vre.getRateExpression()));
                throw new RuntimeException("MathSystemHash doesn't yet support spatial models");
            } else if (equations[j] instanceof MembraneRegionEquation) {
                // hash.addSymbol(new MathSystemHash.VariableDerivative(var,mre.getRateExpression()));
                throw new RuntimeException("MathSystemHash doesn't yet support spatial models");
            } else if (equations[j] instanceof FilamentRegionEquation) {
                // hash.addSymbol(new MathSystemHash.VariableDerivative(var,fre.getRateExpression()));
                throw new RuntimeException("MathSystemHash doesn't yet support spatial models");
            } else if (equations[j] instanceof OdeEquation) {
                OdeEquation ode = (OdeEquation) equations[j];
                hash.addSymbol(new MathSystemHash.VariableDerivative(var, ode.getRateExpression()));
            }
        }
    }
    return hash;
}
Also used : MembraneRegionVariable(cbit.vcell.math.MembraneRegionVariable) FilamentVariable(cbit.vcell.math.FilamentVariable) VolVariable(cbit.vcell.math.VolVariable) VolumeRegionVariable(cbit.vcell.math.VolumeRegionVariable) MemVariable(cbit.vcell.math.MemVariable) FilamentRegionVariable(cbit.vcell.math.FilamentRegionVariable) Variable(cbit.vcell.math.Variable) VolumeRegionEquation(cbit.vcell.math.VolumeRegionEquation) OdeEquation(cbit.vcell.math.OdeEquation) FilamentRegionEquation(cbit.vcell.math.FilamentRegionEquation) MembraneRegionEquation(cbit.vcell.math.MembraneRegionEquation) PdeEquation(cbit.vcell.math.PdeEquation) Equation(cbit.vcell.math.Equation) SubDomain(cbit.vcell.math.SubDomain) PdeEquation(cbit.vcell.math.PdeEquation) FilamentRegionEquation(cbit.vcell.math.FilamentRegionEquation) OdeEquation(cbit.vcell.math.OdeEquation) VolumeRegionEquation(cbit.vcell.math.VolumeRegionEquation) MembraneRegionEquation(cbit.vcell.math.MembraneRegionEquation)

Aggregations

MembraneRegionEquation (cbit.vcell.math.MembraneRegionEquation)5 MembraneRegionVariable (cbit.vcell.math.MembraneRegionVariable)4 OdeEquation (cbit.vcell.math.OdeEquation)4 PdeEquation (cbit.vcell.math.PdeEquation)4 SubDomain (cbit.vcell.math.SubDomain)4 Variable (cbit.vcell.math.Variable)4 Constant (cbit.vcell.math.Constant)3 Equation (cbit.vcell.math.Equation)3 FastInvariant (cbit.vcell.math.FastInvariant)3 FastRate (cbit.vcell.math.FastRate)3 FastSystem (cbit.vcell.math.FastSystem)3 JumpCondition (cbit.vcell.math.JumpCondition)3 MemVariable (cbit.vcell.math.MemVariable)3 VolVariable (cbit.vcell.math.VolVariable)3 Expression (cbit.vcell.parser.Expression)3 SubVolume (cbit.vcell.geometry.SubVolume)2 SurfaceClass (cbit.vcell.geometry.SurfaceClass)2 EventAssignment (cbit.vcell.mapping.BioEvent.EventAssignment)2 LocalParameter (cbit.vcell.mapping.ParameterContext.LocalParameter)2 SpeciesContextSpecParameter (cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter)2