use of cbit.vcell.math.ReservedVariable in project vcell by virtualcell.
the class DataSetControllerImpl method evaluateFunction.
/**
* Insert the method's description here.
* Creation date: (10/13/00 9:13:52 AM)
* @return cbit.vcell.simdata.SimDataBlock
* @param user cbit.vcell.server.User
* @param simResults cbit.vcell.simdata.SimResults
* @param function cbit.vcell.math.Function
* @param time double
*/
private SimDataBlock evaluateFunction(OutputContext outputContext, final VCDataIdentifier vcdID, VCData simData, AnnotatedFunction function, double time) throws ExpressionException, DataAccessException, IOException, MathException {
Expression exp = new Expression(function.getExpression());
exp = SolverUtilities.substituteSizeAndNormalFunctions(exp, function.getFunctionType().getVariableDomain());
exp.bindExpression(simData);
exp = fieldFunctionSubstitution(outputContext, vcdID, exp);
//
// get Dependent datasets
//
// variables are indexed by a number, t=0, x=1, y=2, z=3, a(i) = 4+i where a's are other variables
// these variables
//
CartesianMesh mesh = null;
if (function.getFunctionType().equals(VariableType.POSTPROCESSING)) {
mesh = ((SimulationData) simData).getPostProcessingMesh(function.getName(), outputContext);
}
if (mesh == null) {
mesh = getMesh(vcdID);
}
String[] dependentIDs = exp.getSymbols();
Vector<SimDataHolder> dataSetList = new Vector<SimDataHolder>();
Vector<DataSetIdentifier> dependencyList = new Vector<DataSetIdentifier>();
int varIndex = TXYZ_OFFSET;
int dataLength = 0;
long lastModified = 0;
VariableType variableType = function.getFunctionType();
if (variableType.equals(VariableType.VOLUME) || variableType.equals(VariableType.POSTPROCESSING)) {
dataLength = mesh.getNumVolumeElements();
} else if (variableType.equals(VariableType.MEMBRANE)) {
dataLength = mesh.getNumMembraneElements();
} else if (variableType.equals(VariableType.VOLUME_REGION)) {
dataLength = mesh.getNumVolumeRegions();
} else if (variableType.equals(VariableType.MEMBRANE_REGION)) {
dataLength = mesh.getNumMembraneRegions();
}
VariableType computedVariableType = null;
int computedDataLength = 0;
for (int i = 0; dependentIDs != null && i < dependentIDs.length; i++) {
SymbolTableEntry ste = exp.getSymbolBinding(dependentIDs[i]);
if (ste instanceof DataSetIdentifier) {
DataSetIdentifier dsi = (DataSetIdentifier) ste;
dependencyList.addElement(dsi);
dsi.setIndex(varIndex++);
if (dsi.getName().endsWith(OutsideVariable.OUTSIDE_VARIABLE_SUFFIX) || dsi.getName().endsWith(InsideVariable.INSIDE_VARIABLE_SUFFIX)) {
String volVarName = dsi.getName().substring(0, dsi.getName().lastIndexOf("_"));
SimDataBlock simDataBlock = getSimDataBlock(outputContext, vcdID, volVarName, time);
lastModified = simDataBlock.getPDEDataInfo().getTimeStamp();
//
if (simDataBlock.getVariableType().equals(VariableType.VOLUME)) {
computedVariableType = VariableType.MEMBRANE;
computedDataLength = mesh.getMembraneElements().length;
//
// if inside/outside volume element dependent, then can only be a membrane type
//
} else if (simDataBlock.getVariableType().equals(VariableType.VOLUME_REGION) && variableType == null) {
computedVariableType = VariableType.MEMBRANE_REGION;
computedDataLength = mesh.getNumMembraneRegions();
}
dataSetList.addElement(simDataBlock);
} else {
SimDataBlock simDataBlock = getSimDataBlock(outputContext, vcdID, dsi.getName(), time);
if (variableType == null || simDataBlock.getVariableType().isExpansionOf(variableType)) {
lastModified = simDataBlock.getPDEDataInfo().getTimeStamp();
computedDataLength = simDataBlock.getData().length;
computedVariableType = simDataBlock.getVariableType();
}
dataSetList.addElement(simDataBlock);
}
} else if (ste instanceof ReservedVariable) {
ReservedVariable rv = (ReservedVariable) ste;
if (rv.isTIME()) {
rv.setIndex(0);
} else if (rv.isX()) {
rv.setIndex(1);
} else if (rv.isY()) {
rv.setIndex(2);
} else if (rv.isZ()) {
rv.setIndex(3);
}
} else if (ste instanceof FieldDataParameterVariable) {
// Field Data
((FieldDataParameterVariable) ste).setIndex(varIndex++);
final double[] steResampledFieldData = ((FieldDataParameterVariable) ste).getResampledFieldData();
final VariableType newVariableType = (steResampledFieldData.length == mesh.getNumVolumeElements() ? VariableType.VOLUME : (steResampledFieldData.length == mesh.getNumMembraneElements() ? VariableType.MEMBRANE : null));
if (newVariableType == null) {
throw new DataAccessException("Couldn't determine VariableType for FieldData");
}
if (variableType != null && !variableType.equals(newVariableType)) {
throw new DataAccessException("Incompatible VariableType for FieldData");
}
SimDataHolder newSimDataHolder = new SimDataHolder() {
public double[] getData() {
return steResampledFieldData;
}
public VariableType getVariableType() {
return newVariableType;
}
};
dataSetList.addElement(newSimDataHolder);
dependencyList.add(new DataSetIdentifier(ste.getName(), newVariableType, ((FieldDataParameterVariable) ste).getDomain()));
if (variableType == null) {
computedVariableType = newVariableType;
computedDataLength = newSimDataHolder.getData().length;
}
}
}
if (computedDataLength <= 0) {
if (lg.isWarnEnabled())
lg.warn("dependencies for function '" + function + "' not found, assuming datalength of volume");
computedDataLength = mesh.getDataLength(VariableType.VOLUME);
computedVariableType = VariableType.VOLUME;
// try {
// computedDataLength = mesh.getDataLength(VariableType.VOLUME);
// computedVariableType = VariableType.VOLUME;
// }catch (MathException e){
// lg.error(e.getMessage(), e);
// throw new RuntimeException("MathException, cannot determine domain for function '"+function+"'");
// }catch (FileNotFoundException e){
// lg.error(e.getMessage(), e);
// throw new RuntimeException("Mesh not found, cannot determine domain for function '"+function+"'");
// }
}
if (!variableType.equals(computedVariableType)) {
System.err.println("function [" + function.getName() + "] variable type [" + variableType.getTypeName() + "] is not equal to computed variable type [" + computedVariableType.getTypeName() + "].");
}
if (dataLength == 0) {
dataLength = computedDataLength;
variableType = computedVariableType;
}
//
// Gradient Info for special processing
//
boolean isGrad = hasGradient(exp);
if (isGrad && !variableType.equals(VariableType.VOLUME)) {
throw new DataAccessException("Gradient function is not implemented for datatype " + variableType.getTypeName());
}
double[] args = new double[varIndex + (isGrad ? 12 * varIndex : 0)];
double[] data = new double[dataLength];
// time
args[0] = time;
// x
args[1] = 0.0;
// y
args[2] = 0.0;
// z
args[3] = 0.0;
String dividedByZeroMsg = "";
for (int i = 0; i < dataLength; i++) {
//
if (variableType.equals(VariableType.VOLUME) || variableType.equals(VariableType.POSTPROCESSING)) {
Coordinate coord = mesh.getCoordinateFromVolumeIndex(i);
args[1] = coord.getX();
args[2] = coord.getY();
args[3] = coord.getZ();
for (int j = 0; j < varIndex - TXYZ_OFFSET; j++) {
SimDataHolder simDataHolder = dataSetList.elementAt(j);
if (simDataHolder.getVariableType().equals(VariableType.VOLUME) || simDataHolder.getVariableType().equals(VariableType.POSTPROCESSING)) {
args[TXYZ_OFFSET + j] = simDataHolder.getData()[i];
} else if (simDataHolder.getVariableType().equals(VariableType.VOLUME_REGION)) {
int volumeIndex = mesh.getVolumeRegionIndex(i);
args[TXYZ_OFFSET + j] = simDataHolder.getData()[volumeIndex];
} else if (simDataHolder.getVariableType().equals(VariableType.POINT_VARIABLE)) {
args[TXYZ_OFFSET + j] = simDataHolder.getData()[0];
}
}
if (isGrad) {
getSpatialNeighborData(mesh, i, varIndex, time, dataSetList, args);
}
} else if (variableType.equals(VariableType.VOLUME_REGION)) {
for (int j = 0; j < varIndex - TXYZ_OFFSET; j++) {
SimDataHolder simDataHolder = dataSetList.elementAt(j);
if (simDataHolder.getVariableType().equals(VariableType.VOLUME_REGION)) {
args[TXYZ_OFFSET + j] = simDataHolder.getData()[i];
} else if (simDataHolder.getVariableType().equals(VariableType.POINT_VARIABLE)) {
args[TXYZ_OFFSET + j] = simDataHolder.getData()[0];
}
}
} else if (variableType.equals(VariableType.MEMBRANE)) {
Coordinate coord = mesh.getCoordinateFromMembraneIndex(i);
args[1] = coord.getX();
args[2] = coord.getY();
args[3] = coord.getZ();
for (int j = 0; j < varIndex - TXYZ_OFFSET; j++) {
DataSetIdentifier dsi = (DataSetIdentifier) dependencyList.elementAt(j);
SimDataHolder simDataHolder = dataSetList.elementAt(j);
if (simDataHolder.getVariableType().equals(VariableType.VOLUME)) {
if (mesh.isChomboMesh()) {
String varName = dsi.getName();
if (dsi.getName().endsWith(InsideVariable.INSIDE_VARIABLE_SUFFIX)) {
varName = varName.substring(0, varName.lastIndexOf(InsideVariable.INSIDE_VARIABLE_SUFFIX));
} else if (dsi.getName().endsWith(OutsideVariable.OUTSIDE_VARIABLE_SUFFIX)) {
varName = varName.substring(0, varName.lastIndexOf(OutsideVariable.OUTSIDE_VARIABLE_SUFFIX));
}
args[TXYZ_OFFSET + j] = getChomboExtrapolatedValues(vcdID, varName, time).getData()[i];
} else {
if (dsi.getName().endsWith(InsideVariable.INSIDE_VARIABLE_SUFFIX)) {
args[TXYZ_OFFSET + j] = interpolateVolDataValToMemb(mesh, i, simDataHolder, true, false);
} else if (dsi.getName().endsWith(OutsideVariable.OUTSIDE_VARIABLE_SUFFIX)) {
args[TXYZ_OFFSET + j] = interpolateVolDataValToMemb(mesh, i, simDataHolder, false, false);
} else {
args[TXYZ_OFFSET + j] = interpolateVolDataValToMemb(mesh, dsi.getDomain(), i, simDataHolder, false);
}
}
} else if (simDataHolder.getVariableType().equals(VariableType.VOLUME_REGION)) {
if (dsi.getName().endsWith(InsideVariable.INSIDE_VARIABLE_SUFFIX)) {
args[TXYZ_OFFSET + j] = interpolateVolDataValToMemb(mesh, i, simDataHolder, true, true);
} else if (dsi.getName().endsWith(OutsideVariable.OUTSIDE_VARIABLE_SUFFIX)) {
args[TXYZ_OFFSET + j] = interpolateVolDataValToMemb(mesh, i, simDataHolder, false, true);
} else {
args[TXYZ_OFFSET + j] = interpolateVolDataValToMemb(mesh, dsi.getDomain(), i, simDataHolder, true);
}
} else if (simDataHolder.getVariableType().equals(VariableType.MEMBRANE)) {
args[TXYZ_OFFSET + j] = simDataHolder.getData()[i];
} else if (simDataHolder.getVariableType().equals(VariableType.MEMBRANE_REGION)) {
int memRegionIndex = mesh.getMembraneRegionIndex(i);
args[TXYZ_OFFSET + j] = simDataHolder.getData()[memRegionIndex];
} else if (simDataHolder.getVariableType().equals(VariableType.POINT_VARIABLE)) {
args[TXYZ_OFFSET + j] = simDataHolder.getData()[0];
}
}
} else if (variableType.equals(VariableType.MEMBRANE_REGION)) {
for (int j = 0; j < varIndex - TXYZ_OFFSET; j++) {
DataSetIdentifier dsi = (DataSetIdentifier) dependencyList.elementAt(j);
SimDataHolder simDataHolder = dataSetList.elementAt(j);
if (simDataHolder.getVariableType().equals(VariableType.VOLUME_REGION) && dsi.getName().endsWith(InsideVariable.INSIDE_VARIABLE_SUFFIX)) {
//
for (int k = 0; k < mesh.getMembraneElements().length; k++) {
if (mesh.getMembraneRegionIndex(k) == i) {
args[TXYZ_OFFSET + j] = interpolateVolDataValToMemb(mesh, i, simDataHolder, true, true);
break;
}
}
} else if (simDataHolder.getVariableType().equals(VariableType.VOLUME_REGION) && dsi.getName().endsWith(OutsideVariable.OUTSIDE_VARIABLE_SUFFIX)) {
//
for (int k = 0; k < mesh.getMembraneElements().length; k++) {
if (mesh.getMembraneRegionIndex(k) == i) {
args[TXYZ_OFFSET + j] = interpolateVolDataValToMemb(mesh, i, simDataHolder, false, true);
break;
}
}
} else if (simDataHolder.getVariableType().equals(VariableType.MEMBRANE)) {
args[TXYZ_OFFSET + j] = simDataHolder.getData()[i];
} else if (simDataHolder.getVariableType().equals(VariableType.MEMBRANE_REGION)) {
int memRegionIndex = i;
args[TXYZ_OFFSET + j] = simDataHolder.getData()[memRegionIndex];
} else if (simDataHolder.getVariableType().equals(VariableType.POINT_VARIABLE)) {
args[TXYZ_OFFSET + j] = simDataHolder.getData()[0];
}
}
}
try {
data[i] = exp.evaluateVector(args);
// if(time ==0){
// System.out.print("non-multi evalFunction ");
// for (int m = 0; m < args.length; m++) {
// System.out.print(args[m]);
// }
// System.out.println(" "+(args[args.length-2]/args[args.length-1]));
// }
} catch (DivideByZeroException e) {
dividedByZeroMsg = e.getMessage();
data[i] = Double.POSITIVE_INFINITY;
}
}
if (dividedByZeroMsg.length() != 0) {
System.out.println("DataSetControllerImpl.evaluateFunction(): DivideByZero " + dividedByZeroMsg);
}
PDEDataInfo pdeDataInfo = new PDEDataInfo(vcdID.getOwner(), vcdID.getID(), function.getName(), time, lastModified);
return new SimDataBlock(pdeDataInfo, data, variableType);
}
Aggregations