use of cbit.vcell.numericstest.SolutionTemplate in project vcell by virtualcell.
the class MathTestingUtilities method constructExactMath.
/**
* constructExactMath()
*
* take an equation of the form:
*
* d A
* --- = F(A,t)
* d t
*
* and create a new equation with a known exact solution 'A_exact' by adding a forcing function R(t)
*
* d A
* --- = F(A,t) + R(t)
* d t
*
* where:
*
* d A_exact
* R(t) = --------- - F(A_exact,t)
* d t
*
* solving for R(t) is done analytically.
*
* Creation date: (1/21/2003 10:47:54 AM)
* @return cbit.vcell.math.MathDescription
* @param mathDesc cbit.vcell.math.MathDescription
*/
public static MathDescription constructExactMath(MathDescription mathDesc, java.util.Random random, ConstructedSolutionTemplate constructedSolutionTemplate) throws ExpressionException, MathException, MappingException {
if (mathDesc.hasFastSystems()) {
throw new RuntimeException("SolverTest.constructExactMath() suppport for fastSystems not yet implemented.");
}
MathDescription exactMath = null;
try {
exactMath = (MathDescription) BeanUtils.cloneSerializable(mathDesc);
exactMath.setDescription("constructed exact solution from MathDescription (" + mathDesc.getName() + ")");
exactMath.setName("exact from " + mathDesc.getName());
} catch (Throwable e) {
e.printStackTrace(System.out);
throw new RuntimeException("error cloning MathDescription: " + e.getMessage());
}
//
// preload the VariableHash with existing Variables (and Constants,Functions,etc) and then sort all at once.
//
VariableHash varHash = new VariableHash();
Enumeration<Variable> enumVar = exactMath.getVariables();
while (enumVar.hasMoreElements()) {
varHash.addVariable(enumVar.nextElement());
}
java.util.Enumeration<SubDomain> subDomainEnum = exactMath.getSubDomains();
while (subDomainEnum.hasMoreElements()) {
SubDomain subDomain = subDomainEnum.nextElement();
Domain domain = new Domain(subDomain);
java.util.Enumeration<Equation> equationEnum = subDomain.getEquations();
if (subDomain instanceof MembraneSubDomain) {
MembraneSubDomain memSubDomain = (MembraneSubDomain) subDomain;
AnalyticSubVolume insideAnalyticSubVolume = (AnalyticSubVolume) exactMath.getGeometry().getGeometrySpec().getSubVolume(memSubDomain.getInsideCompartment().getName());
Function[] outwardNormalFunctions = getOutwardNormal(insideAnalyticSubVolume.getExpression(), "_" + insideAnalyticSubVolume.getName());
for (int i = 0; i < outwardNormalFunctions.length; i++) {
varHash.addVariable(outwardNormalFunctions[i]);
}
}
while (equationEnum.hasMoreElements()) {
Equation equation = equationEnum.nextElement();
if (equation.getExactSolution() != null) {
throw new RuntimeException("exact solution already exists");
}
Enumeration<Constant> origMathConstants = mathDesc.getConstants();
if (equation instanceof OdeEquation) {
OdeEquation odeEquation = (OdeEquation) equation;
Expression substitutedRateExp = substituteWithExactSolution(odeEquation.getRateExpression(), (CompartmentSubDomain) subDomain, exactMath);
SolutionTemplate solutionTemplate = constructedSolutionTemplate.getSolutionTemplate(equation.getVariable().getName(), subDomain.getName());
String varName = odeEquation.getVariable().getName();
String initName = null;
while (origMathConstants.hasMoreElements()) {
Constant constant = origMathConstants.nextElement();
if (constant.getName().startsWith(varName + "_" + subDomain.getName() + DiffEquMathMapping.MATH_FUNC_SUFFIX_SPECIES_INIT_CONC_UNIT_PREFIX)) {
initName = constant.getName();
}
}
String exactName = varName + "_" + subDomain.getName() + "_exact";
String errorName = varName + "_" + subDomain.getName() + "_error";
String origRateName = "_" + varName + "_" + subDomain.getName() + "_origRate";
String substitutedRateName = "_" + varName + "_" + subDomain.getName() + "_substitutedRate";
String exactTimeDerivativeName = "_" + varName + "_" + subDomain.getName() + "_exact_dt";
Expression exactExp = solutionTemplate.getTemplateExpression();
Expression errorExp = new Expression(exactName + " - " + varName);
Expression origRateExp = new Expression(odeEquation.getRateExpression());
Expression exactTimeDerivativeExp = exactExp.differentiate("t").flatten();
Expression newRate = new Expression(origRateName + " - " + substitutedRateName + " + " + exactTimeDerivativeName);
Constant[] constants = solutionTemplate.getConstants();
for (int i = 0; i < constants.length; i++) {
varHash.addVariable(constants[i]);
}
Expression initExp = new Expression(exactExp);
initExp.substituteInPlace(new Expression("t"), new Expression(0.0));
varHash.addVariable(new Function(initName, initExp.flatten(), domain));
varHash.addVariable(new Function(exactName, exactExp, domain));
varHash.addVariable(new Function(errorName, errorExp, domain));
varHash.addVariable(new Function(exactTimeDerivativeName, exactTimeDerivativeExp, domain));
varHash.addVariable(new Function(origRateName, origRateExp, domain));
varHash.addVariable(new Function(substitutedRateName, substitutedRateExp, domain));
odeEquation.setRateExpression(newRate);
odeEquation.setInitialExpression(new Expression(initName));
odeEquation.setExactSolution(new Expression(exactName));
} else if (equation instanceof PdeEquation) {
PdeEquation pdeEquation = (PdeEquation) equation;
Expression substitutedRateExp = substituteWithExactSolution(pdeEquation.getRateExpression(), (CompartmentSubDomain) subDomain, exactMath);
SolutionTemplate solutionTemplate = constructedSolutionTemplate.getSolutionTemplate(equation.getVariable().getName(), subDomain.getName());
String varName = pdeEquation.getVariable().getName();
String initName = null;
while (origMathConstants.hasMoreElements()) {
Constant constant = origMathConstants.nextElement();
if (constant.getName().startsWith(varName + "_" + subDomain.getName() + DiffEquMathMapping.MATH_FUNC_SUFFIX_SPECIES_INIT_CONC_UNIT_PREFIX)) {
initName = constant.getName();
}
}
String diffusionRateName = "_" + varName + "_" + subDomain.getName() + "_diffusionRate";
String exactName = varName + "_" + subDomain.getName() + "_exact";
String errorName = varName + "_" + subDomain.getName() + "_error";
String origRateName = "_" + varName + "_" + subDomain.getName() + "_origRate";
String substitutedRateName = "_" + varName + "_" + subDomain.getName() + "_substitutedRate";
String exactTimeDerivativeName = "_" + varName + "_" + subDomain.getName() + "_exact_dt";
String exactDxName = "_" + varName + "_" + subDomain.getName() + "_exact_dx";
String exactDyName = "_" + varName + "_" + subDomain.getName() + "_exact_dy";
String exactDzName = "_" + varName + "_" + subDomain.getName() + "_exact_dz";
String exactDx2Name = "_" + varName + "_" + subDomain.getName() + "_exact_dx2";
String exactDy2Name = "_" + varName + "_" + subDomain.getName() + "_exact_dy2";
String exactDz2Name = "_" + varName + "_" + subDomain.getName() + "_exact_dz2";
String exactLaplacianName = "_" + varName + "_" + subDomain.getName() + "_exact_laplacian";
Expression exactExp = solutionTemplate.getTemplateExpression();
Expression errorExp = new Expression(exactName + " - " + varName);
Expression origRateExp = new Expression(pdeEquation.getRateExpression());
Expression initExp = new Expression(exactExp);
initExp.substituteInPlace(new Expression("t"), new Expression(0.0));
initExp = initExp.flatten();
Expression exactTimeDerivativeExp = exactExp.differentiate("t").flatten();
Expression exactDxExp = exactExp.differentiate("x").flatten();
Expression exactDx2Exp = exactDxExp.differentiate("x").flatten();
Expression exactDyExp = exactExp.differentiate("y").flatten();
Expression exactDy2Exp = exactDxExp.differentiate("y").flatten();
Expression exactDzExp = exactExp.differentiate("z").flatten();
Expression exactDz2Exp = exactDxExp.differentiate("z").flatten();
Expression exactLaplacianExp = Expression.add(Expression.add(exactDx2Exp, exactDy2Exp), exactDz2Exp).flatten();
Expression newRate = new Expression(origRateName + " - " + substitutedRateName + " - ((" + diffusionRateName + ")*" + exactLaplacianName + ")" + " + " + exactTimeDerivativeName);
Constant[] constants = solutionTemplate.getConstants();
for (int i = 0; i < constants.length; i++) {
varHash.addVariable(constants[i]);
}
varHash.addVariable(new Function(initName, initExp, domain));
varHash.addVariable(new Function(diffusionRateName, new Expression(pdeEquation.getDiffusionExpression()), domain));
varHash.addVariable(new Function(exactName, exactExp, domain));
varHash.addVariable(new Function(errorName, errorExp, domain));
varHash.addVariable(new Function(exactTimeDerivativeName, exactTimeDerivativeExp, domain));
varHash.addVariable(new Function(origRateName, origRateExp, domain));
varHash.addVariable(new Function(substitutedRateName, substitutedRateExp, domain));
varHash.addVariable(new Function(exactDxName, exactDxExp, domain));
varHash.addVariable(new Function(exactDyName, exactDyExp, domain));
varHash.addVariable(new Function(exactDzName, exactDzExp, domain));
varHash.addVariable(new Function(exactDx2Name, exactDx2Exp, domain));
varHash.addVariable(new Function(exactDy2Name, exactDy2Exp, domain));
varHash.addVariable(new Function(exactDz2Name, exactDz2Exp, domain));
varHash.addVariable(new Function(exactLaplacianName, exactLaplacianExp, domain));
pdeEquation.setRateExpression(newRate);
pdeEquation.setInitialExpression(new Expression(initName));
pdeEquation.setDiffusionExpression(new Expression(diffusionRateName));
pdeEquation.setExactSolution(new Expression(exactName));
CompartmentSubDomain compartmentSubDomain = (CompartmentSubDomain) subDomain;
if (compartmentSubDomain.getBoundaryConditionXm().isDIRICHLET()) {
Expression origExp = pdeEquation.getBoundaryXm();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryXm(new Expression(origExp + "-" + substitutedExp + "+" + exactExp));
} else {
pdeEquation.setBoundaryXm(exactExp);
}
} else if (compartmentSubDomain.getBoundaryConditionXm().isNEUMANN()) {
Expression origExp = pdeEquation.getBoundaryXm();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryXm(new Expression(origExp + "-" + substitutedExp + "-" + diffusionRateName + "*" + exactDxName));
} else {
pdeEquation.setBoundaryXm(new Expression("-" + diffusionRateName + "*" + exactDxName));
}
} else {
throw new RuntimeException("unsupported boundary condition type " + compartmentSubDomain.getBoundaryConditionXm());
}
if (compartmentSubDomain.getBoundaryConditionXp().isDIRICHLET()) {
Expression origExp = pdeEquation.getBoundaryXp();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryXp(new Expression(origExp + "-" + substitutedExp + "+" + exactExp));
} else {
pdeEquation.setBoundaryXp(exactExp);
}
} else if (compartmentSubDomain.getBoundaryConditionXp().isNEUMANN()) {
Expression origExp = pdeEquation.getBoundaryXp();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryXp(new Expression(origExp + "-" + substitutedExp + "+" + diffusionRateName + "*" + exactDxName));
} else {
pdeEquation.setBoundaryXp(new Expression(diffusionRateName + "*" + exactDxName));
}
} else {
throw new RuntimeException("unsupported boundary condition type " + compartmentSubDomain.getBoundaryConditionXp());
}
if (compartmentSubDomain.getBoundaryConditionYm().isDIRICHLET()) {
Expression origExp = pdeEquation.getBoundaryYm();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryYm(new Expression(origExp + "-" + substitutedExp + "+" + exactExp));
} else {
pdeEquation.setBoundaryYm(exactExp);
}
} else if (compartmentSubDomain.getBoundaryConditionYm().isNEUMANN()) {
Expression origExp = pdeEquation.getBoundaryYm();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryYm(new Expression(origExp + "-" + substitutedExp + "-" + diffusionRateName + "*" + exactDyName));
} else {
pdeEquation.setBoundaryYm(new Expression("-" + diffusionRateName + "*" + exactDyName));
}
} else {
throw new RuntimeException("unsupported boundary condition type " + compartmentSubDomain.getBoundaryConditionYm());
}
if (compartmentSubDomain.getBoundaryConditionYp().isDIRICHLET()) {
Expression origExp = pdeEquation.getBoundaryYp();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryYp(new Expression(origExp + "-" + substitutedExp + "+" + exactExp));
} else {
pdeEquation.setBoundaryYp(exactExp);
}
} else if (compartmentSubDomain.getBoundaryConditionYp().isNEUMANN()) {
Expression origExp = pdeEquation.getBoundaryYp();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryYp(new Expression(origExp + "-" + substitutedExp + "+" + diffusionRateName + "*" + exactDyName));
} else {
pdeEquation.setBoundaryYp(new Expression(diffusionRateName + "*" + exactDyName));
}
} else {
throw new RuntimeException("unsupported boundary condition type " + compartmentSubDomain.getBoundaryConditionYp());
}
if (compartmentSubDomain.getBoundaryConditionZm().isDIRICHLET()) {
Expression origExp = pdeEquation.getBoundaryZm();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryZm(new Expression(origExp + "-" + substitutedExp + "+" + exactExp));
} else {
pdeEquation.setBoundaryZm(exactExp);
}
} else if (compartmentSubDomain.getBoundaryConditionZm().isNEUMANN()) {
Expression origExp = pdeEquation.getBoundaryZm();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryZm(new Expression(origExp + "-" + substitutedExp + "-" + diffusionRateName + "*" + exactDzName));
} else {
pdeEquation.setBoundaryZm(new Expression("-" + diffusionRateName + "*" + exactDzName));
}
} else {
throw new RuntimeException("unsupported boundary condition type " + compartmentSubDomain.getBoundaryConditionXm());
}
if (compartmentSubDomain.getBoundaryConditionZp().isDIRICHLET()) {
Expression origExp = pdeEquation.getBoundaryZp();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryZp(new Expression(origExp + "-" + substitutedExp + "+" + exactExp));
} else {
pdeEquation.setBoundaryZp(exactExp);
}
} else if (compartmentSubDomain.getBoundaryConditionZp().isNEUMANN()) {
Expression origExp = pdeEquation.getBoundaryZp();
if (origExp != null) {
Expression substitutedExp = substituteWithExactSolution(origExp, compartmentSubDomain, exactMath);
pdeEquation.setBoundaryZp(new Expression(origExp + "-" + substitutedExp + "+" + diffusionRateName + "*" + exactDzName));
} else {
pdeEquation.setBoundaryZp(new Expression(diffusionRateName + "*" + exactDzName));
}
} else {
throw new RuntimeException("unsupported boundary condition type " + compartmentSubDomain.getBoundaryConditionZp());
}
} else {
throw new RuntimeException("SolverTest.constructedExactMath(): equation type " + equation.getClass().getName() + " not yet implemented");
}
}
if (subDomain instanceof MembraneSubDomain) {
MembraneSubDomain membraneSubDomain = (MembraneSubDomain) subDomain;
Enumeration<JumpCondition> enumJumpConditions = membraneSubDomain.getJumpConditions();
while (enumJumpConditions.hasMoreElements()) {
JumpCondition jumpCondition = enumJumpConditions.nextElement();
Expression origInfluxExp = jumpCondition.getInFluxExpression();
Expression origOutfluxExp = jumpCondition.getOutFluxExpression();
Expression substitutedInfluxExp = substituteWithExactSolution(origInfluxExp, membraneSubDomain, exactMath);
Expression substitutedOutfluxExp = substituteWithExactSolution(origOutfluxExp, membraneSubDomain, exactMath);
String varName = jumpCondition.getVariable().getName();
String origInfluxName = "_" + varName + "_" + subDomain.getName() + "_origInflux";
String origOutfluxName = "_" + varName + "_" + subDomain.getName() + "_origOutflux";
String substitutedInfluxName = "_" + varName + "_" + subDomain.getName() + "_substitutedInflux";
String substitutedOutfluxName = "_" + varName + "_" + subDomain.getName() + "_substitutedOutflux";
String diffusionRateInsideName = "_" + varName + "_" + membraneSubDomain.getInsideCompartment().getName() + "_diffusionRate";
String diffusionRateOutsideName = "_" + varName + "_" + membraneSubDomain.getOutsideCompartment().getName() + "_diffusionRate";
String exactInsideDxName = "_" + varName + "_" + membraneSubDomain.getInsideCompartment().getName() + "_exact_dx";
String exactInsideDyName = "_" + varName + "_" + membraneSubDomain.getInsideCompartment().getName() + "_exact_dy";
String exactInsideDzName = "_" + varName + "_" + membraneSubDomain.getInsideCompartment().getName() + "_exact_dz";
String exactOutsideDxName = "_" + varName + "_" + membraneSubDomain.getOutsideCompartment().getName() + "_exact_dx";
String exactOutsideDyName = "_" + varName + "_" + membraneSubDomain.getOutsideCompartment().getName() + "_exact_dy";
String exactOutsideDzName = "_" + varName + "_" + membraneSubDomain.getOutsideCompartment().getName() + "_exact_dz";
String outwardNormalXName = "_" + membraneSubDomain.getInsideCompartment().getName() + "_Nx";
String outwardNormalYName = "_" + membraneSubDomain.getInsideCompartment().getName() + "_Ny";
String outwardNormalZName = "_" + membraneSubDomain.getInsideCompartment().getName() + "_Nz";
String exactInfluxName = "_" + varName + "_" + membraneSubDomain.getName() + "_exactInflux";
String exactOutfluxName = "_" + varName + "_" + membraneSubDomain.getName() + "_exactOutflux";
Expression exactInfluxExp = new Expression(diffusionRateInsideName + " * (" + outwardNormalXName + "*" + exactInsideDxName + " + " + outwardNormalYName + "*" + exactInsideDyName + " + " + outwardNormalZName + "*" + exactInsideDzName + ")");
Expression exactOutfluxExp = new Expression("-" + diffusionRateOutsideName + " * (" + outwardNormalXName + "*" + exactOutsideDxName + " + " + outwardNormalYName + "*" + exactOutsideDyName + " + " + outwardNormalZName + "*" + exactOutsideDzName + ")");
Expression newInfluxExp = new Expression(origInfluxName + " - " + substitutedInfluxName + " + " + exactInfluxName);
Expression newOutfluxExp = new Expression(origOutfluxName + " - " + substitutedOutfluxName + " + " + exactOutfluxName);
varHash.addVariable(new Function(origInfluxName, origInfluxExp, domain));
varHash.addVariable(new Function(origOutfluxName, origOutfluxExp, domain));
varHash.addVariable(new Function(exactInfluxName, exactInfluxExp, domain));
varHash.addVariable(new Function(exactOutfluxName, exactOutfluxExp, domain));
varHash.addVariable(new Function(substitutedInfluxName, substitutedInfluxExp, domain));
varHash.addVariable(new Function(substitutedOutfluxName, substitutedOutfluxExp, domain));
jumpCondition.setInFlux(newInfluxExp);
jumpCondition.setOutFlux(newOutfluxExp);
}
}
}
exactMath.setAllVariables(varHash.getAlphabeticallyOrderedVariables());
if (!exactMath.isValid()) {
throw new RuntimeException("generated Math is not valid: " + exactMath.getWarning());
}
return exactMath;
}
use of cbit.vcell.numericstest.SolutionTemplate in project vcell by virtualcell.
the class SolutionTemplateTableModel method setValueAt.
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (rowIndex < 0 || rowIndex >= getRowCount()) {
throw new RuntimeException("SolutionTemplateTableModel.setValueAt(), row = " + rowIndex + " out of range [" + 0 + "," + (getRowCount() - 1) + "]");
}
if (columnIndex < 0 || columnIndex >= NUM_COLUMNS) {
throw new RuntimeException("SolutionTemplateTableModel.setValueAt(), column = " + columnIndex + " out of range [" + 0 + "," + (NUM_COLUMNS - 1) + "]");
}
SolutionTemplate solnTemplate = getConstructedSolutionTemplate().getSolutionTemplates()[rowIndex];
switch(columnIndex) {
case COLUMN_EXPRESSION:
{
try {
if (aValue instanceof Expression) {
Expression exp = (Expression) aValue;
solnTemplate.setTemplateExpression(exp);
} else if (aValue instanceof String) {
String newExpressionString = (String) aValue;
solnTemplate.setTemplateExpression(new Expression(newExpressionString));
}
fireTableRowsUpdated(rowIndex, rowIndex);
} catch (cbit.vcell.parser.ExpressionException e) {
e.printStackTrace(System.out);
//
throw new RuntimeException(e.getMessage());
}
break;
}
}
}
Aggregations