use of cbit.vcell.math.SubDomain in project vcell by virtualcell.
the class ITextWriter method writeSubDomainsEquationsAsImages.
// currently not used.
protected void writeSubDomainsEquationsAsImages(Section mathDescSection, MathDescription mathDesc) {
Enumeration<SubDomain> subDomains = mathDesc.getSubDomains();
Expression[] expArray;
Section volDomains = mathDescSection.addSection("Volume Domains", mathDescSection.depth() + 1);
Section memDomains = mathDescSection.addSection("Membrane Domains", mathDescSection.depth() + 1);
// arbitrary
int scale = 1, height = 200;
int viewableWidth = (int) (document.getPageSize().width() - document.leftMargin() - document.rightMargin());
BufferedImage dummy = new BufferedImage(viewableWidth, height, BufferedImage.TYPE_3BYTE_BGR);
while (subDomains.hasMoreElements()) {
SubDomain subDomain = subDomains.nextElement();
Enumeration<Equation> equationsList = subDomain.getEquations();
ArrayList<Expression> expList = new ArrayList<Expression>();
while (equationsList.hasMoreElements()) {
Equation equ = equationsList.nextElement();
try {
Enumeration<Expression> enum_equ = equ.getTotalExpressions();
while (enum_equ.hasMoreElements()) {
Expression exp = new Expression(enum_equ.nextElement());
expList.add(exp.flatten());
}
} catch (ExpressionException ee) {
System.err.println("Unable to process the equation for subdomain: " + subDomain.getName());
ee.printStackTrace();
continue;
}
}
expArray = (Expression[]) expList.toArray(new Expression[expList.size()]);
Section tempSection = null;
if (subDomain instanceof CompartmentSubDomain) {
tempSection = volDomains.addSection(subDomain.getName(), volDomains.depth() + 1);
} else if (subDomain instanceof MembraneSubDomain) {
tempSection = memDomains.addSection(subDomain.getName(), memDomains.depth() + 1);
}
try {
Dimension dim = ExpressionCanvas.getExpressionImageSize(expArray, (Graphics2D) dummy.getGraphics());
System.out.println("Image dim: " + dim.width + " " + dim.height);
BufferedImage bufferedImage = new BufferedImage((int) dim.getWidth() * scale, (int) dim.getHeight() * scale, BufferedImage.TYPE_3BYTE_BGR);
ExpressionCanvas.getExpressionAsImage(expArray, bufferedImage, scale);
// Table imageTable = null;;
com.lowagie.text.Image expImage = com.lowagie.text.Image.getInstance(bufferedImage, null);
expImage.setAlignment(com.lowagie.text.Image.LEFT);
if (viewableWidth < expImage.scaledWidth()) {
expImage.scaleToFit(viewableWidth, expImage.height());
System.out.println("SubDomain expresions After scaling: " + expImage.scaledWidth());
}
/*Cell imageCell = new Cell();
imageCell.add(expImage);
if (imageTable == null) {
imageTable = getTable(1, 100, 1, 1, 0);
}
imageTable.setTableFitsPage(false);
imageTable.setCellsFitPage(false);
imageTable.addCell(imageCell);
imageTable.setWidth(100);
tempSection.add(imageTable);*/
tempSection.add(expImage);
} catch (Exception e) {
System.err.println("Unable to add subdomain equation image to report.");
e.printStackTrace();
}
}
if (volDomains.isEmpty()) {
mathDescSection.remove(volDomains);
}
if (memDomains.isEmpty()) {
mathDescSection.remove(memDomains);
}
}
use of cbit.vcell.math.SubDomain in project vcell by virtualcell.
the class ITextWriter method writeSubDomainsEquationsAsText.
protected void writeSubDomainsEquationsAsText(Section mathDescSection, MathDescription mathDesc) throws DocumentException {
Enumeration<SubDomain> subDomains = mathDesc.getSubDomains();
Section volDomains = mathDescSection.addSection("Volume Domains", mathDescSection.depth() + 1);
Section memDomains = mathDescSection.addSection("Membrane Domains", mathDescSection.depth() + 1);
Section filDomains = mathDescSection.addSection("Filament Domains", mathDescSection.depth() + 1);
while (subDomains.hasMoreElements()) {
Section tempSection = null;
SubDomain subDomain = subDomains.nextElement();
if (subDomain instanceof CompartmentSubDomain) {
tempSection = volDomains.addSection(subDomain.getName(), volDomains.depth() + 1);
} else if (subDomain instanceof MembraneSubDomain) {
tempSection = memDomains.addSection(subDomain.getName(), memDomains.depth() + 1);
} else if (subDomain instanceof FilamentSubDomain) {
tempSection = filDomains.addSection(subDomain.getName(), filDomains.depth() + 1);
}
Enumeration<Equation> equationsList = subDomain.getEquations();
while (equationsList.hasMoreElements()) {
Equation equ = equationsList.nextElement();
writeEquation(tempSection, equ);
}
if (subDomain.getFastSystem() != null) {
writeFastSystem(tempSection, subDomain.getFastSystem());
}
if (subDomain instanceof MembraneSubDomain) {
Enumeration<JumpCondition> jcList = ((MembraneSubDomain) subDomain).getJumpConditions();
while (jcList.hasMoreElements()) {
JumpCondition jc = jcList.nextElement();
writeJumpCondition(tempSection, jc);
}
}
}
if (volDomains.isEmpty()) {
mathDescSection.remove(volDomains);
}
if (memDomains.isEmpty()) {
mathDescSection.remove(memDomains);
}
if (filDomains.isEmpty()) {
mathDescSection.remove(filDomains);
}
}
use of cbit.vcell.math.SubDomain 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.SubDomain in project vcell by virtualcell.
the class SimulationSymbolTable method hasTimeVaryingDiffusionOrAdvection.
public boolean hasTimeVaryingDiffusionOrAdvection(Variable variable) throws MathException, ExpressionException {
Enumeration<SubDomain> enum1 = simulation.getMathDescription().getSubDomains();
while (enum1.hasMoreElements()) {
SubDomain subDomain = enum1.nextElement();
Equation equation = subDomain.getEquation(variable);
//
if (equation instanceof PdeEquation) {
Vector<Expression> spatialExpressionList = new Vector<Expression>();
spatialExpressionList.add(((PdeEquation) equation).getDiffusionExpression());
if (((PdeEquation) equation).getVelocityX() != null) {
spatialExpressionList.add(((PdeEquation) equation).getVelocityX());
}
if (((PdeEquation) equation).getVelocityY() != null) {
spatialExpressionList.add(((PdeEquation) equation).getVelocityY());
}
if (((PdeEquation) equation).getVelocityZ() != null) {
spatialExpressionList.add(((PdeEquation) equation).getVelocityZ());
}
for (int i = 0; i < spatialExpressionList.size(); i++) {
Expression spatialExp = spatialExpressionList.elementAt(i);
spatialExp = substituteFunctions(spatialExp);
String[] symbols = spatialExp.getSymbols();
if (symbols != null) {
for (int j = 0; j < symbols.length; j++) {
SymbolTableEntry entry = spatialExp.getSymbolBinding(symbols[j]);
if (entry instanceof ReservedVariable) {
if (((ReservedVariable) entry).isTIME()) {
return true;
}
}
if (entry instanceof VolVariable) {
return true;
}
if (entry instanceof VolumeRegionVariable) {
return true;
}
if (entry instanceof MemVariable || entry instanceof MembraneRegionVariable) {
return true;
}
}
}
}
}
}
return false;
}
use of cbit.vcell.math.SubDomain 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;
}
Aggregations