use of cbit.vcell.math.MembraneSubDomain in project vcell by virtualcell.
the class FiniteVolumeFileWriter method writeMembranes.
/**
*MEMBRANE_BEGIN subVolume0_subVolume1_membrane subVolume0 subVolume1
*
*BOUNDARY_CONDITIONS value value value value
*
*EQUATION_BEGIN varMem
*INITIAL (x > 0.75);
*REACTION 0.0;
*DIFFUSION 1.0;
*BOUNDARY_XM (x > 0.75);
*BOUNDARY_XP (x > 0.75);
*BOUNDARY_YM (x > 0.75);
*BOUNDARY_YP (x > 0.75);
*EQUATION_END
*
*JUMP_CONDITION_BEGIN varVol
*INFLUX 0.0;
*OUTFLUX 0.0;
*JUMP_CONDITION_END
*
*MEMBRANE_END
* @throws ExpressionException
* @throws MathException
*/
private void writeMembranes() throws ExpressionException, MathException {
Simulation simulation = simTask.getSimulation();
MathDescription mathDesc = simulation.getMathDescription();
Enumeration<SubDomain> enum1 = mathDesc.getSubDomains();
while (enum1.hasMoreElements()) {
SubDomain sd = enum1.nextElement();
if (sd instanceof MembraneSubDomain) {
MembraneSubDomain msd = (MembraneSubDomain) sd;
printWriter.println("MEMBRANE_BEGIN " + msd.getName() + " " + msd.getInsideCompartment().getName() + " " + msd.getOutsideCompartment().getName());
printWriter.println();
writeMembrane_VarContext(msd);
writeMembrane_jumpConditions(msd);
writeFastSystem(msd);
printWriter.println("MEMBRANE_END");
printWriter.println();
}
}
}
use of cbit.vcell.math.MembraneSubDomain in project vcell by virtualcell.
the class SimulationSymbolTable method getFunctionVariableType.
/**
* Insert the method's description here.
* Creation date: (2/19/2004 11:17:15 AM)
* @return cbit.vcell.simdata.VariableType
* @param function cbit.vcell.math.Function
* @param variableNames java.lang.String[]
* @param variableTypes cbit.vcell.simdata.VariableType[]
*/
public static VariableType getFunctionVariableType(Function function, MathDescription mathDescription, String[] variableNames, VariableType[] variableTypes, boolean isSpatial) throws InconsistentDomainException {
if (!isSpatial) {
return VariableType.NONSPATIAL;
}
VariableType domainFuncType = null;
// initial guess, restrict variable type to be consistent with domain.
if (function.getDomain() != null) {
String domainName = function.getDomain().getName();
if (mathDescription != null) {
SubDomain subdomain = mathDescription.getSubDomain(domainName);
if (subdomain instanceof MembraneSubDomain) {
domainFuncType = VariableType.MEMBRANE_REGION;
} else {
domainFuncType = VariableType.VOLUME_REGION;
}
}
}
Expression exp = function.getExpression();
String[] symbols = exp.getSymbols();
ArrayList<VariableType> varTypeList = new ArrayList<VariableType>();
boolean bExplicitFunctionOfSpace = false;
if (symbols != null) {
for (int j = 0; j < symbols.length; j++) {
if (symbols[j].equals(ReservedVariable.X.getName()) || symbols[j].equals(ReservedVariable.Y.getName()) || symbols[j].equals(ReservedVariable.Z.getName())) {
bExplicitFunctionOfSpace = true;
continue;
}
for (int k = 0; k < variableNames.length; k++) {
if (symbols[j].equals(variableNames[k])) {
varTypeList.add(variableTypes[k]);
break;
} else if (symbols[j].equals(variableNames[k] + InsideVariable.INSIDE_VARIABLE_SUFFIX) || symbols[j].equals(variableNames[k] + OutsideVariable.OUTSIDE_VARIABLE_SUFFIX)) {
if (variableTypes[k].equals(VariableType.VOLUME)) {
varTypeList.add(VariableType.MEMBRANE);
} else if (variableTypes[k].equals(VariableType.VOLUME_REGION)) {
varTypeList.add(VariableType.MEMBRANE_REGION);
}
break;
}
}
}
}
// Size Functions
Set<FunctionInvocation> sizeFunctionInvocationSet = SolverUtilities.getSizeFunctionInvocations(function.getExpression());
for (FunctionInvocation fi : sizeFunctionInvocationSet) {
String functionName = fi.getFunctionName();
if (functionName.equals(MathFunctionDefinitions.Function_regionArea_current.getFunctionName())) {
varTypeList.add(VariableType.MEMBRANE_REGION);
} else if (functionName.equals(MathFunctionDefinitions.Function_regionVolume_current.getFunctionName())) {
varTypeList.add(VariableType.VOLUME_REGION);
}
}
// Membrane Normal Functions
FunctionInvocation[] functionInvocations = function.getExpression().getFunctionInvocations(null);
for (FunctionInvocation fi : functionInvocations) {
String functionName = fi.getFunctionName();
if (functionName.equals(MathFunctionDefinitions.Function_normalX.getFunctionName()) || functionName.equals(MathFunctionDefinitions.Function_normalY.getFunctionName())) {
varTypeList.add(VariableType.MEMBRANE);
}
}
FieldFunctionArguments[] fieldFuncArgs = FieldUtilities.getFieldFunctionArguments(function.getExpression());
if (fieldFuncArgs != null && fieldFuncArgs.length > 0) {
varTypeList.add(fieldFuncArgs[0].getVariableType());
}
VariableType funcType = domainFuncType;
for (VariableType vt : varTypeList) {
if (funcType == null) {
funcType = vt;
} else {
//
if (vt.isExpansionOf(funcType)) {
funcType = vt;
} else if (vt.equals(VariableType.VOLUME)) {
if (funcType.equals(VariableType.MEMBRANE_REGION)) {
funcType = VariableType.MEMBRANE;
}
} else if (vt.equals(VariableType.VOLUME_REGION)) {
} else if (vt.equals(VariableType.MEMBRANE)) {
if (domainFuncType != null && domainFuncType.getVariableDomain().equals(VariableDomain.VARIABLEDOMAIN_VOLUME)) {
throw new InconsistentDomainException("Function '" + function.getName() + "' defined on a volume subdomain '" + function.getDomain().getName() + "' references a variable or a function defined on a membrane subdomain");
}
} else if (vt.equals(VariableType.MEMBRANE_REGION)) {
if (funcType.equals(VariableType.VOLUME)) {
if (domainFuncType != null && domainFuncType.getVariableDomain().equals(VariableDomain.VARIABLEDOMAIN_VOLUME)) {
throw new InconsistentDomainException("Function '" + function.getName() + "' defined on '" + function.getDomain().getName() + "' references a size function defined on a membrane");
}
funcType = VariableType.MEMBRANE;
} else if (funcType.equals(VariableType.VOLUME_REGION)) {
if (domainFuncType != null && domainFuncType.getVariableDomain().equals(VariableDomain.VARIABLEDOMAIN_VOLUME)) {
throw new InconsistentDomainException("Function '" + function.getName() + "' defined on '" + function.getDomain().getName() + "' references a size function defined on a membrane");
}
funcType = VariableType.MEMBRANE_REGION;
}
} else if (vt.incompatibleWith(funcType)) {
throw new InconsistentDomainException("Function domains conflict between variable domains '" + vt.getDefaultLabel() + "' and '" + funcType.getDefaultLabel() + " for function " + function.getName());
}
}
}
//
if (funcType != null && bExplicitFunctionOfSpace) {
if (funcType.equals(VariableType.MEMBRANE_REGION)) {
funcType = VariableType.MEMBRANE;
} else if (funcType.equals(VariableType.VOLUME_REGION)) {
funcType = VariableType.VOLUME;
} else if (funcType.equals(VariableType.CONTOUR_REGION)) {
funcType = VariableType.CONTOUR;
}
}
if (funcType == null) {
// no knowledge from expression, default variable type
return VariableType.VOLUME;
}
return funcType;
}
use of cbit.vcell.math.MembraneSubDomain in project vcell by virtualcell.
the class SimulationWarning method analyzeDiffusion.
/**
* make sure diffusion expressions are constants, store for later use
* @throws ExpressionException
*/
private static Map<MembraneSubDomain, List<DiffusionValue>> analyzeDiffusion(Simulation simulation, double timeStep, IssueContext issueContext, List<Issue> issueList) throws ExpressionException {
Map<MembraneSubDomain, List<DiffusionValue>> diffusionValuesMap = new IdentityHashMap<>();
diffusionValuesMap.clear();
MutableDouble value = new MutableDouble();
MathDescription cm = simulation.getMathDescription();
Objects.requireNonNull(cm);
MathDescription localMath = new MathDescription(cm);
SimulationSymbolTable symTable = new SimulationSymbolTable(simulation, 0);
Map<MembraneSubDomain, List<DiffusionValue>> dvMap = new HashMap<>();
double maxDiffValue = Double.MIN_VALUE;
List<DiffusionValue> diffusionList = new ArrayList<>();
for (SubDomain sd : localMath.getSubDomainCollection()) {
final boolean isMembrane = sd instanceof MembraneSubDomain;
diffusionList.clear();
for (ParticleProperties pp : sd.getParticleProperties()) {
String name = pp.getVariable().getName();
Expression diffExp = pp.getDiffusion();
Expression flattened = MathUtilities.substituteFunctions(diffExp, symTable).flatten();
if (isConstant(flattened, value)) {
if (isMembrane) {
DiffusionValue dv = new DiffusionValue(name, value.doubleValue());
maxDiffValue = Math.max(maxDiffValue, dv.value);
diffusionList.add(dv);
}
} else {
String s = "Smoldyn only supports constant diffusion, " + name + " is variable";
Issue i = new Issue(simulation, issueContext, IssueCategory.SMOLYDN_DIFFUSION, s, s, Severity.ERROR);
issueList.add(i);
}
}
if (isMembrane && !diffusionList.isEmpty()) {
dvMap.put((MembraneSubDomain) sd, diffusionList);
}
}
diffusionValuesMap.putAll(dvMap);
MeshSpecification ms = simulation.getMeshSpecification();
Geometry g = ms.getGeometry();
int dim = g.getDimension();
double minDelta = Double.MAX_VALUE;
switch(dim) {
case 3:
minDelta = Math.min(minDelta, ms.getDz(true));
// fall-through
case 2:
minDelta = Math.min(minDelta, ms.getDy(true));
// fall-through
case 1:
minDelta = Math.min(minDelta, ms.getDx(true));
break;
default:
throw new RuntimeException("Invalid dimension " + dim + " for smoldyn solver");
}
double minArea = minDelta * minDelta / 2;
double limit = PRECHECK_LIMIT_ADJUST * minArea / maxDiffValue;
boolean warn = (timeStep > limit);
if (lg.isDebugEnabled()) {
lg.debug("Min delta " + minDelta + ", min area " + minArea + " time limit " + limit + " timeStep " + timeStep + " -> warn = " + warn);
}
if (warn) {
String s = "Time step " + timeStep + " may be too large, performing further analysis ...";
Issue i = new Issue(simulation, issueContext, IssueCategory.SMOLYDN_DIFFUSION, s, s, Severity.WARNING);
issueList.add(i);
}
lg.debug("end of diffusion analysis");
return diffusionValuesMap;
}
use of cbit.vcell.math.MembraneSubDomain in project vcell by virtualcell.
the class Xmlproducer method getXML.
/**
* This method returns a XML representation of a SubDomain object type.
* Creation date: (3/2/2001 1:13:30 PM)
* @return Element
* @param param cbit.vcell.math.SubDomain
*/
private Element getXML(SubDomain param) throws XmlParseException {
Element e = null;
if (param instanceof CompartmentSubDomain) {
e = getXML((CompartmentSubDomain) param);
} else if (param instanceof FilamentSubDomain) {
e = getXML((FilamentSubDomain) param);
} else if (param instanceof MembraneSubDomain) {
e = getXML((MembraneSubDomain) param);
} else if (param instanceof PointSubDomain) {
e = getXML((PointSubDomain) param);
}
transcribeComments(param, e);
return e;
}
use of cbit.vcell.math.MembraneSubDomain in project vcell by virtualcell.
the class MathDescriptionTreeModel method createBaseTree.
/**
* Insert the method's description here.
* Creation date: (11/28/00 1:06:51 PM)
* @return cbit.vcell.desktop.BioModelNode
* @param docManager cbit.vcell.clientdb.DocumentManager
*/
private BioModelNode createBaseTree() {
if (getMathDescription() == null) {
return new BioModelNode(" ", false);
}
//
// make root node
//
BioModelNode rootNode = new BioModelNode("math description", true);
//
// create subTree of Constants
//
BioModelNode constantRootNode = new BioModelNode("constants", true);
Enumeration<Constant> enum1 = getMathDescription().getConstants();
while (enum1.hasMoreElements()) {
Constant constant = enum1.nextElement();
BioModelNode constantNode = new BioModelNode(constant, false);
constantRootNode.add(constantNode);
}
if (constantRootNode.getChildCount() > 0) {
rootNode.add(constantRootNode);
}
//
// create subTree of Functions
//
BioModelNode functionRootNode = new BioModelNode("functions", true);
Enumeration<Function> enum2 = getMathDescription().getFunctions();
while (enum2.hasMoreElements()) {
Function function = enum2.nextElement();
BioModelNode functionNode = new BioModelNode(function, false);
functionRootNode.add(functionNode);
}
if (functionRootNode.getChildCount() > 0) {
rootNode.add(functionRootNode);
}
//
// create subTree of VolumeSubDomains and MembraneSubDomains
//
BioModelNode volumeRootNode = new BioModelNode("volume domains", true);
BioModelNode membraneRootNode = new BioModelNode("membrane domains", true);
Enumeration<SubDomain> enum3 = getMathDescription().getSubDomains();
while (enum3.hasMoreElements()) {
SubDomain subDomain = enum3.nextElement();
if (subDomain instanceof cbit.vcell.math.CompartmentSubDomain) {
CompartmentSubDomain volumeSubDomain = (CompartmentSubDomain) subDomain;
BioModelNode volumeSubDomainNode = new BioModelNode(volumeSubDomain, true);
if (// stochastic subtree
getMathDescription().isNonSpatialStoch()) {
// add stoch variable initial conditions
BioModelNode varIniConditionNode = new BioModelNode("variable_initial_conditions", true);
for (VarIniCondition varIni : volumeSubDomain.getVarIniConditions()) {
BioModelNode varIniNode = new BioModelNode(varIni, false);
varIniConditionNode.add(varIniNode);
}
volumeSubDomainNode.add(varIniConditionNode);
// add jump processes
for (JumpProcess jp : volumeSubDomain.getJumpProcesses()) {
BioModelNode jpNode = new BioModelNode(jp, true);
// add probability rate.
String probRate = "P_" + jp.getName();
BioModelNode prNode = new BioModelNode("probability_rate = " + probRate, false);
jpNode.add(prNode);
// add Actions
Enumeration<Action> actions = Collections.enumeration(jp.getActions());
while (actions.hasMoreElements()) {
Action action = actions.nextElement();
BioModelNode actionNode = new BioModelNode(action, false);
jpNode.add(actionNode);
}
volumeSubDomainNode.add(jpNode);
}
} else // non-stochastic subtree
{
//
// add equation children
//
Enumeration<Equation> eqnEnum = volumeSubDomain.getEquations();
while (eqnEnum.hasMoreElements()) {
Equation equation = eqnEnum.nextElement();
BioModelNode equationNode = new BioModelNode(equation, false);
volumeSubDomainNode.add(equationNode);
}
//
// add fast system
//
FastSystem fastSystem = volumeSubDomain.getFastSystem();
if (fastSystem != null) {
BioModelNode fsNode = new BioModelNode(fastSystem, true);
Enumeration<FastInvariant> enumFI = fastSystem.getFastInvariants();
while (enumFI.hasMoreElements()) {
FastInvariant fi = enumFI.nextElement();
fsNode.add(new BioModelNode(fi, false));
}
Enumeration<FastRate> enumFR = fastSystem.getFastRates();
while (enumFR.hasMoreElements()) {
FastRate fr = enumFR.nextElement();
fsNode.add(new BioModelNode(fr, false));
}
volumeSubDomainNode.add(fsNode);
}
}
volumeRootNode.add(volumeSubDomainNode);
} else if (subDomain instanceof MembraneSubDomain) {
MembraneSubDomain membraneSubDomain = (MembraneSubDomain) subDomain;
BioModelNode membraneSubDomainNode = new BioModelNode(membraneSubDomain, true);
//
// add equation children
//
Enumeration<Equation> eqnEnum = membraneSubDomain.getEquations();
while (eqnEnum.hasMoreElements()) {
Equation equation = eqnEnum.nextElement();
BioModelNode equationNode = new BioModelNode(equation, false);
membraneSubDomainNode.add(equationNode);
}
//
// add jump condition children
//
Enumeration<JumpCondition> jcEnum = membraneSubDomain.getJumpConditions();
while (jcEnum.hasMoreElements()) {
JumpCondition jumpCondition = jcEnum.nextElement();
BioModelNode jcNode = new BioModelNode(jumpCondition, false);
membraneSubDomainNode.add(jcNode);
}
//
// add fast system
//
FastSystem fastSystem = membraneSubDomain.getFastSystem();
if (fastSystem != null) {
BioModelNode fsNode = new BioModelNode(fastSystem, true);
Enumeration<FastInvariant> enumFI = fastSystem.getFastInvariants();
while (enumFI.hasMoreElements()) {
FastInvariant fi = enumFI.nextElement();
fsNode.add(new BioModelNode(fi, false));
}
Enumeration<FastRate> enumFR = fastSystem.getFastRates();
while (enumFR.hasMoreElements()) {
FastRate fr = enumFR.nextElement();
fsNode.add(new BioModelNode(fr, false));
}
membraneSubDomainNode.add(fsNode);
}
membraneRootNode.add(membraneSubDomainNode);
}
}
if (volumeRootNode.getChildCount() > 0) {
rootNode.add(volumeRootNode);
}
if (membraneRootNode.getChildCount() > 0) {
rootNode.add(membraneRootNode);
}
return rootNode;
}
Aggregations