use of cbit.vcell.math.CompartmentSubDomain in project vcell by virtualcell.
the class ComsolModelBuilder method getVCCModel.
public static VCCModel getVCCModel(SimulationJob vcellSimJob) throws ExpressionException {
MathDescription vcellMathDesc = vcellSimJob.getSimulation().getMathDescription();
Geometry vcellGeometry = vcellMathDesc.getGeometry();
GeometrySpec vcellGeometrySpec = vcellGeometry.getGeometrySpec();
int vcellDim = vcellGeometrySpec.getDimension();
VCCModel model = new VCCModel("Model", vcellDim);
model.modelpath = "D:\\Developer\\eclipse\\workspace_refactor\\comsol_java\\src";
model.comments = "Untitled\n\n";
VCCModelNode comp1 = new VCCModelNode("comp1");
model.modelnodes.add(comp1);
// if (vcellDim != 2){
// throw new RuntimeException("expecting 2D simulation");
// }
//
// assume initial geometry is circle centered at 0.5, 0.5 of radius 0.3
//
// String comsolOutsideDomainName = "dif1";
// String comsolInsideDomainName = "c1";
VCCGeomSequence geom1 = new VCCGeomSequence("geom1", vcellDim);
model.geometrysequences.add(geom1);
VCCMeshSequence mesh1 = new VCCMeshSequence("mesh1", geom1);
model.meshes.add(mesh1);
VCCStudy std1 = new VCCStudy("std1");
model.study = std1;
TimeBounds timeBounds = vcellSimJob.getSimulation().getSolverTaskDescription().getTimeBounds();
TimeStep timeStep = vcellSimJob.getSimulation().getSolverTaskDescription().getTimeStep();
String beginTime = Double.toString(timeBounds.getStartingTime());
String endTime = Double.toString(timeBounds.getEndingTime());
String step = Double.toString(timeStep.getDefaultTimeStep());
VCCStudyFeature time = new VCCTransientStudyFeature("time", beginTime, step, endTime);
std1.features.add(time);
if (vcellGeometrySpec.getImage() != null) {
throw new RuntimeException("image-based geometries not yet supported by VCell's COMSOL model builder");
}
if (vcellGeometrySpec.getNumSubVolumes() == 0) {
throw new RuntimeException("no subvolumes defined in geometry");
}
if (vcellGeometrySpec.getNumAnalyticOrCSGSubVolumes() != vcellGeometrySpec.getNumSubVolumes()) {
throw new RuntimeException("only analytic and CSG subvolumes currently supported by VCell's COMSOL model builder");
}
//
// add geometry for all subvolumes
//
HashMap<String, VCCGeomFeature> subvolumeNameFeatureMap = new HashMap<String, VCCGeomFeature>();
SubVolume[] subVolumes = vcellGeometrySpec.getSubVolumes();
for (int i = 0; i < subVolumes.length; i++) {
SubVolume subvolume = subVolumes[i];
if (subvolume instanceof CSGObject) {
CSGObject vcellCSGObject = (CSGObject) subvolume;
CSGNode vcellCSGNode = vcellCSGObject.getRoot();
ArrayList<VCCGeomFeature> geomFeatureList = new ArrayList<VCCGeomFeature>();
VCCGeomFeature feature = csgVisitor(vcellCSGNode, geomFeatureList, subvolume.getName());
geom1.geomfeatures.addAll(geomFeatureList);
if (i == 0) {
// first subvolume (on top in ordinals) doesn't need any differencing
subvolumeNameFeatureMap.put(subvolume.getName(), feature);
} else {
// have to subtract union of prior subvolumes
ArrayList<VCCGeomFeature> priorFeatures = new ArrayList<VCCGeomFeature>();
for (int j = 0; j < i; j++) {
CSGObject priorCSGObject = (CSGObject) subVolumes[j];
CSGNode priorCSGNode = priorCSGObject.getRoot();
geomFeatureList.clear();
VCCGeomFeature priorFeature = csgVisitor(priorCSGNode, geomFeatureList, subvolume.getName());
priorFeatures.add(priorFeature);
geom1.geomfeatures.addAll(geomFeatureList);
}
VCCDifference diff = new VCCDifference("diff" + subvolume.getName(), Keep.off);
diff.input.add(feature);
diff.input2.addAll(priorFeatures);
geom1.geomfeatures.add(diff);
subvolumeNameFeatureMap.put(subvolume.getName(), diff);
}
} else {
throw new RuntimeException("only CSG subvolumes currently supported by VCell's COMSOL model builder");
}
}
//
// add geometry for all surfaceClasses
//
HashMap<String, VCCGeomFeature> surfaceclassNameFeatureMap = new HashMap<String, VCCGeomFeature>();
SurfaceClass[] surfaceClasses = vcellGeometry.getGeometrySurfaceDescription().getSurfaceClasses();
for (int i = 0; i < surfaceClasses.length; i++) {
SurfaceClass surfaceClass = surfaceClasses[i];
Set<SubVolume> adjacentSubvolumes = surfaceClass.getAdjacentSubvolumes();
if (adjacentSubvolumes.size() != 2) {
throw new RuntimeException("expecting two adjacent subvolumes for surface " + surfaceClass.getName() + " in COMSOL model builder");
}
// find adjacent Geometry Features (for subvolumes)
Iterator<SubVolume> svIter = adjacentSubvolumes.iterator();
SubVolume subvolume0 = svIter.next();
SubVolume subvolume1 = svIter.next();
ArrayList<VCCGeomFeature> adjacentFeatures = new ArrayList<VCCGeomFeature>();
adjacentFeatures.add(subvolumeNameFeatureMap.get(subvolume0.getName()));
adjacentFeatures.add(subvolumeNameFeatureMap.get(subvolume1.getName()));
String name = "inter_" + subvolume0.getName() + "_" + subvolume1.getName();
// surfaces are dimension N-1
int entitydim = vcellDim - 1;
VCCIntersectionSelection intersect_subvolumes = new VCCIntersectionSelection(name, entitydim);
intersect_subvolumes.input.addAll(adjacentFeatures);
geom1.geomfeatures.add(intersect_subvolumes);
surfaceclassNameFeatureMap.put(surfaceClass.getName(), intersect_subvolumes);
}
SimulationSymbolTable symbolTable = new SimulationSymbolTable(vcellSimJob.getSimulation(), vcellSimJob.getJobIndex());
//
for (SubDomain subDomain : Collections.list(vcellMathDesc.getSubDomains())) {
for (Equation equ : subDomain.getEquationCollection()) {
if (equ instanceof PdeEquation || equ instanceof OdeEquation) {
VCCGeomFeature geomFeature = null;
final int dim;
if (subDomain instanceof CompartmentSubDomain) {
geomFeature = subvolumeNameFeatureMap.get(subDomain.getName());
dim = vcellDim;
} else if (subDomain instanceof MembraneSubDomain) {
geomFeature = surfaceclassNameFeatureMap.get(subDomain.getName());
dim = vcellDim - 1;
} else {
throw new RuntimeException("subdomains of type '" + subDomain.getClass().getSimpleName() + "' not yet supported in COMSOL model builder");
}
if (geomFeature == null) {
throw new RuntimeException("cannot find COMSOL geometry feature named " + subDomain.getName() + " in COMSOL model builder");
}
VCCConvectionDiffusionEquation cdeq = new VCCConvectionDiffusionEquation("cdeq_" + equ.getVariable().getName(), geom1, geomFeature, dim);
cdeq.fieldName = equ.getVariable().getName();
cdeq.initial = MathUtilities.substituteModelParameters(equ.getInitialExpression(), symbolTable).flatten().infix();
cdeq.sourceTerm_f = MathUtilities.substituteModelParameters(equ.getRateExpression(), symbolTable).flatten().infix();
if (equ instanceof PdeEquation) {
PdeEquation pde = (PdeEquation) equ;
cdeq.diffTerm_c = MathUtilities.substituteModelParameters(pde.getDiffusionExpression(), symbolTable).flatten().infix();
if (subDomain instanceof CompartmentSubDomain) {
CompartmentSubDomain compartmentSubdomain = (CompartmentSubDomain) subDomain;
ArrayList<String> be = new ArrayList<String>();
if (pde.getVelocityX() != null) {
be.add(MathUtilities.substituteModelParameters(pde.getVelocityX(), symbolTable).flatten().infix());
} else {
be.add("0");
}
if (vcellDim >= 2) {
if (pde.getVelocityY() != null) {
be.add(MathUtilities.substituteModelParameters(pde.getVelocityY(), symbolTable).flatten().infix());
} else {
be.add("0");
}
}
if (vcellDim == 3) {
if (pde.getVelocityY() != null) {
be.add(MathUtilities.substituteModelParameters(pde.getVelocityZ(), symbolTable).flatten().infix());
} else {
be.add("0");
}
}
cdeq.advection_be = be.toArray(new String[vcellDim]);
//
// look for membrane boundary conditions for this variable
//
MembraneSubDomain[] membraneSubdomains = vcellMathDesc.getMembraneSubDomains(compartmentSubdomain);
for (MembraneSubDomain membraneSubdomain : membraneSubdomains) {
JumpCondition jumpCondition = membraneSubdomain.getJumpCondition((VolVariable) pde.getVariable());
if (jumpCondition != null) {
Expression fluxExpr = null;
if (membraneSubdomain.getInsideCompartment() == compartmentSubdomain) {
fluxExpr = jumpCondition.getInFluxExpression();
} else if (membraneSubdomain.getOutsideCompartment() == compartmentSubdomain) {
fluxExpr = jumpCondition.getOutFluxExpression();
}
String name = equ.getVariable().getName() + "_flux_" + membraneSubdomain.getName();
VCCGeomFeature selection = surfaceclassNameFeatureMap.get(membraneSubdomain.getName());
VCCFluxBoundary fluxBoundary = new VCCFluxBoundary(name, selection, vcellDim - 1);
fluxBoundary.flux_g = MathUtilities.substituteModelParameters(fluxExpr, symbolTable).flatten().infix();
cdeq.features.add(fluxBoundary);
}
}
}
}
model.physics.add(cdeq);
}
}
}
//
return model;
}
use of cbit.vcell.math.CompartmentSubDomain in project vcell by virtualcell.
the class SmoldynFileWriter method writeRuntimeCommands.
// uncomment for debug
/*private void writeGraphicsLegend() throws MathException{
try {
java.awt.image.BufferedImage cmapImage = new java.awt.image.BufferedImage(200, particleVariableList.size()*30,java.awt.image.BufferedImage.TYPE_INT_RGB);
Graphics g = cmapImage.getGraphics();
for (int i = 0; i < particleVariableList.size(); i ++) {
Color c = colors[i];
System.out.println("color for legend: " + "red--"+ c.getRed() + " green--" + c.getGreen() + " blue--" + c.getBlue());
String variableName = getVariableName(particleVariableList.get(i),null);
g.setColor(c);
g.drawString(variableName, 5, 30*i + 20);
g.fillRect(105, 30*i + 10, 20, 10);
}
g.dispose();
File tmpFile = File.createTempFile("legend", ".jpg");
FileOutputStream fios = null;
try {
printWriter.println("# legend file: " + tmpFile.getAbsolutePath());
fios = new FileOutputStream(tmpFile);
ImageIO.write(cmapImage,"jpg",fios);
} finally {
if(fios != null) {fios.close();}
}
} catch (Exception e) {
e.printStackTrace();
throw new MathException(e.getMessage());
}
}*/
private void writeRuntimeCommands() throws SolverException, DivideByZeroException, DataAccessException, IOException, MathException, ExpressionException {
printWriter.println("# " + SmoldynVCellMapper.SmoldynKeyword.killmolincmpt + " runtime command to kill molecules misplaced during initial condtions");
for (ParticleVariable pv : particleVariableList) {
CompartmentSubDomain varDomain = mathDesc.getCompartmentSubDomain(pv.getDomain().getName());
if (varDomain == null) {
continue;
}
boolean bkillMol = false;
ArrayList<ParticleInitialCondition> iniConditionList = varDomain.getParticleProperties(pv).getParticleInitialConditions();
for (ParticleInitialCondition iniCon : iniConditionList) {
if (iniCon instanceof ParticleInitialConditionConcentration) {
try {
subsituteFlattenToConstant(((ParticleInitialConditionConcentration) iniCon).getDistribution());
} catch (// can not be evaluated to a constant
Exception e) {
bkillMol = true;
break;
}
}
}
if (bkillMol) {
Enumeration<SubDomain> subDomainEnumeration = mathDesc.getSubDomains();
while (subDomainEnumeration.hasMoreElements()) {
SubDomain subDomain = subDomainEnumeration.nextElement();
if (subDomain instanceof CompartmentSubDomain && varDomain != subDomain) {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.cmd + " " + SmoldynVCellMapper.SmoldynKeyword.B + " " + SmoldynVCellMapper.SmoldynKeyword.killmolincmpt + " " + pv.getName() + "(" + SmoldynVCellMapper.SmoldynKeyword.all + ") " + subDomain.getName());
}
}
}
}
printWriter.println();
// write command to kill molecules on membrane for adsortption to nothing
printWriter.println("# kill membrane molecues that are absorbed (to nothing)");
for (String killMolCmd : killMolCommands) {
printWriter.println(killMolCmd);
}
printWriter.println();
printWriter.println("# runtime command");
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.cmd + " " + SmoldynVCellMapper.SmoldynKeyword.E + " " + VCellSmoldynKeyword.vcellPrintProgress);
if (outputFile != null && cartesianMesh != null) {
OutputTimeSpec ots = simulation.getSolverTaskDescription().getOutputTimeSpec();
if (ots.isUniform()) {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.output_files + " " + outputFile.getName());
ISize sampleSize = simulation.getMeshSpecification().getSamplingSize();
TimeStep timeStep = simulation.getSolverTaskDescription().getTimeStep();
int n = (int) Math.round(((UniformOutputTimeSpec) ots).getOutputTimeStep() / timeStep.getDefaultTimeStep());
if (simulation.getSolverTaskDescription().getSmoldynSimulationOptions().isSaveParticleLocations()) {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.cmd + " " + SmoldynVCellMapper.SmoldynKeyword.N + " " + n + " " + SmoldynVCellMapper.SmoldynKeyword.incrementfile + " " + outputFile.getName());
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.cmd + " " + SmoldynVCellMapper.SmoldynKeyword.N + " " + n + " " + SmoldynVCellMapper.SmoldynKeyword.listmols + " " + outputFile.getName());
}
// DON'T CHANGE THE ORDER HERE.
// DataProcess must be before vcellWriteOutput
writeDataProcessor();
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.cmd + " " + SmoldynVCellMapper.SmoldynKeyword.N + " " + n + " " + VCellSmoldynKeyword.vcellWriteOutput + " begin");
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.cmd + " " + SmoldynVCellMapper.SmoldynKeyword.N + " " + n + " " + VCellSmoldynKeyword.vcellWriteOutput + " " + VCellSmoldynKeyword.dimension + " " + dimension);
printWriter.print(SmoldynVCellMapper.SmoldynKeyword.cmd + " " + SmoldynVCellMapper.SmoldynKeyword.N + " " + n + " " + VCellSmoldynKeyword.vcellWriteOutput + " " + VCellSmoldynKeyword.sampleSize + " " + sampleSize.getX());
if (dimension > 1) {
printWriter.print(" " + sampleSize.getY());
if (dimension > 2) {
printWriter.print(" " + sampleSize.getZ());
}
}
printWriter.println();
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.cmd + " " + SmoldynVCellMapper.SmoldynKeyword.N + " " + n + " " + VCellSmoldynKeyword.vcellWriteOutput + " " + VCellSmoldynKeyword.numMembraneElements + " " + cartesianMesh.getNumMembraneElements());
for (ParticleVariable pv : particleVariableList) {
String type = pv instanceof MembraneParticleVariable ? VCellSmoldynKeyword.membrane.name() : VCellSmoldynKeyword.volume.name();
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.cmd + " " + SmoldynVCellMapper.SmoldynKeyword.N + " " + n + " " + VCellSmoldynKeyword.vcellWriteOutput + " " + VCellSmoldynKeyword.variable + " " + pv.getName() + " " + type + " " + pv.getDomain().getName());
}
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.cmd + " " + SmoldynVCellMapper.SmoldynKeyword.N + " " + n + " " + VCellSmoldynKeyword.vcellWriteOutput + " end");
} else {
throw new SolverException(SolverDescription.Smoldyn.getDisplayLabel() + " only supports uniform output.");
}
}
printWriter.println();
}
use of cbit.vcell.math.CompartmentSubDomain in project vcell by virtualcell.
the class SmoldynFileWriter method writeInitialConcentration.
private int writeInitialConcentration(ParticleInitialConditionConcentration initialConcentration, SubDomain subDomain, Variable variable, String variableName, StringBuilder sb) throws ExpressionException, MathException {
SimpleSymbolTable simpleSymbolTable = new SimpleSymbolTable(new String[] { ReservedVariable.X.getName(), ReservedVariable.Y.getName(), ReservedVariable.Z.getName() });
Expression disExpression = new Expression(initialConcentration.getDistribution());
disExpression.bindExpression(simulationSymbolTable);
disExpression = simulationSymbolTable.substituteFunctions(disExpression).flatten();
disExpression.bindExpression(simpleSymbolTable);
double[] values = new double[3];
if (dimension == 1) {
if (disExpression.getSymbolBinding(ReservedVariable.Y.getName()) != null || disExpression.getSymbolBinding(ReservedVariable.Z.getName()) != null) {
throw new MathException(VCellErrorMessages.getSmoldynWrongCoordinates("'y' or 'z'", dimension, variable, disExpression));
}
} else if (dimension == 2) {
if (disExpression.getSymbolBinding(ReservedVariable.Z.getName()) != null) {
throw new MathException(VCellErrorMessages.getSmoldynWrongCoordinates("'z'", dimension, variable, disExpression));
}
}
int totalCount = 0;
StringBuilder localsb = new StringBuilder();
if (subDomain instanceof CompartmentSubDomain) {
MeshSpecification meshSpecification = simulation.getMeshSpecification();
ISize sampleSize = meshSpecification.getSamplingSize();
int numX = sampleSize.getX();
int numY = dimension < 2 ? 1 : sampleSize.getY();
int numZ = dimension < 3 ? 1 : sampleSize.getZ();
boolean bCellCentered = simulation.hasCellCenteredMesh();
double dx = meshSpecification.getDx(bCellCentered);
double dy = meshSpecification.getDy(bCellCentered);
double dz = meshSpecification.getDz(bCellCentered);
Origin origin = resampledGeometry.getGeometrySpec().getOrigin();
double ox = origin.getX();
double oy = origin.getY();
double oz = origin.getZ();
Extent extent = resampledGeometry.getExtent();
double ex = extent.getX();
double ey = extent.getY();
double ez = extent.getZ();
int offset = 0;
for (int k = 0; k < numZ; k++) {
double centerz = oz + k * dz;
double loz = Math.max(oz, centerz - dz / 2);
double hiz = Math.min(oz + ez, centerz + dz / 2);
double lz = hiz - loz;
values[2] = centerz;
for (int j = 0; j < numY; j++) {
double centery = oy + j * dy;
double loy = Math.max(oy, centery - dy / 2);
double hiy = Math.min(oy + ey, centery + dy / 2);
values[1] = centery;
double ly = hiy - loy;
for (int i = 0; i < numX; i++) {
int regionIndex = resampledGeometry.getGeometrySurfaceDescription().getRegionImage().getRegionInfoFromOffset(offset).getRegionIndex();
offset++;
GeometricRegion region = resampledGeometry.getGeometrySurfaceDescription().getGeometricRegions(regionIndex);
if (region instanceof VolumeGeometricRegion) {
if (!((VolumeGeometricRegion) region).getSubVolume().getName().equals(subDomain.getName())) {
continue;
}
}
double centerx = ox + i * dx;
double lox = Math.max(ox, centerx - dx / 2);
double hix = Math.min(ox + ex, centerx + dx / 2);
double lx = hix - lox;
values[0] = centerx;
double volume = lx;
if (dimension > 1) {
volume *= ly;
if (dimension > 2) {
volume *= lz;
}
}
double expectedCount = disExpression.evaluateVector(values) * volume;
if (expectedCount <= 0) {
continue;
}
long count = dist.nextPoisson(expectedCount);
if (count <= 0) {
continue;
}
totalCount += count;
localsb.append(SmoldynVCellMapper.SmoldynKeyword.mol + " " + count + " " + variableName + " " + (float) lox + "-" + (float) hix);
if (lg.isDebugEnabled()) {
lg.debug("Component subdomain " + variableName + " count " + count);
}
if (dimension > 1) {
localsb.append(" " + loy + "-" + hiy);
if (dimension > 2) {
localsb.append(" " + loz + "-" + hiz);
}
}
localsb.append("\n");
}
}
}
// otherwise we append the distributed molecules in different small boxes
try {
subsituteFlattenToConstant(disExpression);
sb.append(SmoldynVCellMapper.SmoldynKeyword.compartment_mol);
sb.append(" " + totalCount + " " + variableName + " " + subDomain.getName() + "\n");
} catch (// can not be evaluated to a constant
Exception e) {
sb.append(localsb);
}
} else if (subDomain instanceof MembraneSubDomain) {
ArrayList<TrianglePanel> trianglePanelList = membraneSubdomainTriangleMap.get(subDomain);
for (TrianglePanel trianglePanel : trianglePanelList) {
Triangle triangle = trianglePanel.triangle;
switch(dimension) {
case 1:
values[0] = triangle.getNodes(0).getX();
break;
case 2:
{
double centroidX = triangle.getNodes(0).getX();
double centroidY = triangle.getNodes(0).getY();
if (triangle.getNodes(0).getX() == triangle.getNodes(1).getX() && triangle.getNodes(0).getY() == triangle.getNodes(1).getY()) {
centroidX += triangle.getNodes(2).getX();
centroidY += triangle.getNodes(2).getY();
} else {
centroidX += triangle.getNodes(1).getX();
centroidY += triangle.getNodes(1).getY();
}
values[0] = centroidX / 2;
values[1] = centroidY / 2;
break;
}
case 3:
{
double centroidX = triangle.getNodes(0).getX() + triangle.getNodes(1).getX() + triangle.getNodes(2).getX();
double centroidY = triangle.getNodes(0).getY() + triangle.getNodes(1).getY() + triangle.getNodes(2).getY();
double centroidZ = triangle.getNodes(0).getZ() + triangle.getNodes(1).getZ() + triangle.getNodes(2).getZ();
values[0] = centroidX / 3;
values[1] = centroidY / 3;
values[2] = centroidZ / 3;
break;
}
}
double expectedCount = disExpression.evaluateVector(values) * triangle.getArea();
if (expectedCount <= 0) {
continue;
}
long count = dist.nextPoisson(expectedCount);
if (count <= 0) {
continue;
}
totalCount += count;
if (lg.isDebugEnabled()) {
lg.debug("Membrane subdomain " + subDomain.getName() + ' ' + variableName + " count " + count);
}
localsb.append(SmoldynVCellMapper.SmoldynKeyword.surface_mol + " " + count + " " + variableName + " " + subDomain.getName() + " " + SmoldynVCellMapper.SmoldynKeyword.tri + " " + trianglePanel.name + "\n");
}
// otherwise we append the distributed molecules in different small boxes
try {
subsituteFlattenToConstant(disExpression);
sb.append(SmoldynVCellMapper.SmoldynKeyword.surface_mol);
sb.append(" " + totalCount + " " + variableName + " " + subDomain.getName() + " " + SmoldynVCellMapper.SmoldynKeyword.all + " " + SmoldynVCellMapper.SmoldynKeyword.all + "\n");
} catch (// can not be evaluated to a constant
Exception e) {
sb.append(localsb);
}
}
if (lg.isDebugEnabled()) {
lg.debug("Subdomain " + subDomain.getName() + ' ' + variableName + " total count " + totalCount);
}
return totalCount;
}
use of cbit.vcell.math.CompartmentSubDomain in project vcell by virtualcell.
the class SmoldynFileWriter method writeWallSurfaces.
private void writeWallSurfaces() throws SolverException {
GeometrySurfaceDescription geometrySurfaceDescription = resampledGeometry.getGeometrySurfaceDescription();
GeometrySpec geometrySpec = resampledGeometry.getGeometrySpec();
SubVolume[] subVolumes = geometrySpec.getSubVolumes();
printWriter.println("# boundaries");
Origin origin = geometrySpec.getOrigin();
Extent extent = geometrySpec.getExtent();
Coordinate lowWall = new Coordinate(origin.getX(), origin.getY(), origin.getZ());
Coordinate highWall = new Coordinate(origin.getX() + extent.getX(), origin.getY() + extent.getY(), origin.getZ() + extent.getZ());
// potential artifact.
if (bHasNoSurface) {
SubDomain subDomain0 = mathDesc.getSubDomains().nextElement();
CompartmentSubDomain compartSubDomain0 = null;
compartSubDomain0 = (CompartmentSubDomain) subDomain0;
// x
if (compartSubDomain0.getBoundaryConditionXm().isPERIODIC()) {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.boundaries + " 0 " + lowWall.getX() + " " + highWall.getX() + " " + SmoldynVCellMapper.SmoldynKeyword.p);
} else {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.low_wall + " 0 " + lowWall.getX() + " " + (compartSubDomain0.getBoundaryConditionXm().isNEUMANN() ? SmoldynVCellMapper.SmoldynKeyword.r : SmoldynVCellMapper.SmoldynKeyword.a));
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.high_wall + " 0 " + highWall.getX() + " " + (compartSubDomain0.getBoundaryConditionXp().isNEUMANN() ? SmoldynVCellMapper.SmoldynKeyword.r : SmoldynVCellMapper.SmoldynKeyword.a));
}
if (dimension > 1) {
// y
if (compartSubDomain0.getBoundaryConditionYm().isPERIODIC()) {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.boundaries + " 1 " + lowWall.getY() + " " + highWall.getY() + " " + SmoldynVCellMapper.SmoldynKeyword.p);
} else {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.low_wall + " 1 " + lowWall.getY() + " " + (compartSubDomain0.getBoundaryConditionYm().isNEUMANN() ? SmoldynVCellMapper.SmoldynKeyword.r : SmoldynVCellMapper.SmoldynKeyword.a));
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.high_wall + " 1 " + highWall.getY() + " " + (compartSubDomain0.getBoundaryConditionYp().isNEUMANN() ? SmoldynVCellMapper.SmoldynKeyword.r : SmoldynVCellMapper.SmoldynKeyword.a));
}
if (dimension > 2) {
// z
if (compartSubDomain0.getBoundaryConditionZm().isPERIODIC()) {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.boundaries + " 2 " + lowWall.getZ() + " " + highWall.getZ() + " " + SmoldynVCellMapper.SmoldynKeyword.p);
} else {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.low_wall + " 2 " + lowWall.getZ() + " " + (compartSubDomain0.getBoundaryConditionZm().isNEUMANN() ? SmoldynVCellMapper.SmoldynKeyword.r : SmoldynVCellMapper.SmoldynKeyword.a));
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.high_wall + " 2 " + highWall.getZ() + " " + (compartSubDomain0.getBoundaryConditionZp().isNEUMANN() ? SmoldynVCellMapper.SmoldynKeyword.r : SmoldynVCellMapper.SmoldynKeyword.a));
}
}
}
printWriter.println();
} else {
// x
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.boundaries + " 0 " + lowWall.getX() + " " + highWall.getX());
if (dimension > 1) {
// y
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.boundaries + " 1 " + lowWall.getY() + " " + highWall.getY());
if (dimension > 2) {
// z
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.boundaries + " 2 " + lowWall.getZ() + " " + highWall.getZ());
}
}
printWriter.println();
// bounding walls as surfaces
// have to find boundary condition type
ISize sampleSize = simulation.getMeshSpecification().getSamplingSize();
int numX = sampleSize.getX();
int numY = dimension < 2 ? 1 : sampleSize.getY();
int numZ = dimension < 3 ? 1 : sampleSize.getZ();
if (dimension > 2) {
int[] k_wall = new int[] { 0, numZ - 1 };
for (int k = 0; k < k_wall.length; k++) {
for (int j = 0; j < numY; j++) {
for (int i = 0; i < numX; i++) {
int volIndex = k_wall[k] * numX * numY + j * numX + i;
for (SubVolume sv : subVolumes) {
// gather all the points in all the regions
GeometricRegion[] geometricRegions = geometrySurfaceDescription.getGeometricRegions(sv);
RegionInfo[] regionInfos = geometrySurfaceDescription.getRegionImage().getRegionInfos();
for (GeometricRegion gr : geometricRegions) {
VolumeGeometricRegion vgr = (VolumeGeometricRegion) gr;
for (RegionInfo ri : regionInfos) {
if (ri.getRegionIndex() == vgr.getRegionID() && ri.isIndexInRegion(volIndex)) {
boundaryZSubVolumes.add(sv);
}
}
}
}
}
}
}
}
if (dimension > 1) {
int[] j_wall = new int[] { 0, numY - 1 };
for (int k = 0; k < numZ; k++) {
for (int j = 0; j < j_wall.length; j++) {
for (int i = 0; i < numX; i++) {
int volIndex = k * numX * numY + j_wall[j] * numX + i;
for (SubVolume sv : subVolumes) {
// gather all the points in all the regions
GeometricRegion[] geometricRegions = geometrySurfaceDescription.getGeometricRegions(sv);
RegionInfo[] regionInfos = geometrySurfaceDescription.getRegionImage().getRegionInfos();
for (GeometricRegion gr : geometricRegions) {
VolumeGeometricRegion vgr = (VolumeGeometricRegion) gr;
for (RegionInfo ri : regionInfos) {
if (ri.getRegionIndex() == vgr.getRegionID() && ri.isIndexInRegion(volIndex)) {
boundaryYSubVolumes.add(sv);
}
}
}
}
}
}
}
}
int[] i_wall = new int[] { 0, numX - 1 };
for (int k = 0; k < numZ; k++) {
for (int j = 0; j < numY; j++) {
for (int i = 0; i < i_wall.length; i++) {
int volIndex = k * numX * numY + j * numX + i_wall[i];
for (SubVolume sv : subVolumes) {
// gather all the points in all the regions
GeometricRegion[] geometricRegions = geometrySurfaceDescription.getGeometricRegions(sv);
RegionInfo[] regionInfos = geometrySurfaceDescription.getRegionImage().getRegionInfos();
for (GeometricRegion gr : geometricRegions) {
VolumeGeometricRegion vgr = (VolumeGeometricRegion) gr;
for (RegionInfo ri : regionInfos) {
if (ri.getRegionIndex() == vgr.getRegionID() && ri.isIndexInRegion(volIndex)) {
boundaryXSubVolumes.add(sv);
}
}
}
}
}
}
}
Set<SubVolume> boundarySubVolumes = new HashSet<SubVolume>();
boundarySubVolumes.addAll(boundaryXSubVolumes);
boundarySubVolumes.addAll(boundaryYSubVolumes);
boundarySubVolumes.addAll(boundaryZSubVolumes);
BoundaryConditionType[] computedBct = new BoundaryConditionType[dimension * 2];
String[] smoldynBct = new String[dimension * 2];
String[] wallNames = new String[] { "Xm", "Xp", "Ym", "Yp", "Zm", "Zp" };
if (boundarySubVolumes.size() >= 1) {
for (SubVolume sv : boundarySubVolumes) {
CompartmentSubDomain csd = (CompartmentSubDomain) mathDesc.getSubDomain(sv.getName());
BoundaryConditionType[] bct = new BoundaryConditionType[] { csd.getBoundaryConditionXm(), csd.getBoundaryConditionXp(), csd.getBoundaryConditionYm(), csd.getBoundaryConditionYp(), csd.getBoundaryConditionZm(), csd.getBoundaryConditionZp() };
if (computedBct[0] == null) {
System.arraycopy(bct, 0, computedBct, 0, dimension * 2);
for (int i = 0; i < dimension * 2; i++) {
if (computedBct[i].isPERIODIC()) {
throw new SolverException("Models with both surfaces and periodic boundary conditions are not supported yet.");
}
smoldynBct[i] = computedBct[i].isDIRICHLET() ? SmoldynVCellMapper.SmoldynKeyword.absorb.name() : SmoldynVCellMapper.SmoldynKeyword.reflect.name();
}
} else {
for (int i = 0; i < dimension * 2; i++) {
if (!computedBct[i].compareEqual(bct[i])) {
throw new SolverException(wallNames[i] + " wall has different boundary conditions");
}
}
}
}
}
printWriter.println("# bounding wall surface");
// X walls
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.start_surface + " " + VCellSmoldynKeyword.bounding_wall_surface_X);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.action + " " + SmoldynVCellMapper.SmoldynKeyword.all + "(" + SmoldynVCellMapper.SmoldynKeyword.up + ") " + SmoldynVCellMapper.SmoldynKeyword.both + " " + SmoldynVCellMapper.SmoldynKeyword.reflect);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.action + " " + SmoldynVCellMapper.SmoldynKeyword.all + " " + SmoldynVCellMapper.SmoldynKeyword.front + " " + smoldynBct[0]);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.action + " " + SmoldynVCellMapper.SmoldynKeyword.all + " " + SmoldynVCellMapper.SmoldynKeyword.back + " " + smoldynBct[1]);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.color + " " + SmoldynVCellMapper.SmoldynKeyword.both + " 1 1 1");
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.polygon + " " + SmoldynVCellMapper.SmoldynKeyword.both + " " + SmoldynVCellMapper.SmoldynKeyword.edge);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.max_panels + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " 2");
// yz walls
switch(dimension) {
case 1:
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " +0 " + lowWall.getX());
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " -0 " + highWall.getX());
break;
case 2:
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " +0 " + lowWall.getX() + " " + lowWall.getY() + " " + extent.getY());
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " -0 " + highWall.getX() + " " + lowWall.getY() + " " + extent.getY());
break;
case 3:
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " +0 " + lowWall.getX() + " " + lowWall.getY() + " " + lowWall.getZ() + " " + extent.getY() + " " + extent.getZ());
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " -0 " + highWall.getX() + " " + lowWall.getY() + " " + lowWall.getZ() + " " + extent.getY() + " " + extent.getZ());
break;
}
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.end_surface);
printWriter.println();
if (dimension > 1) {
// Y walls
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.start_surface + " " + VCellSmoldynKeyword.bounding_wall_surface_Y);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.action + " " + SmoldynVCellMapper.SmoldynKeyword.all + "(" + SmoldynVCellMapper.SmoldynKeyword.up + ") " + SmoldynVCellMapper.SmoldynKeyword.both + " " + SmoldynVCellMapper.SmoldynKeyword.reflect);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.action + " " + SmoldynVCellMapper.SmoldynKeyword.all + " " + SmoldynVCellMapper.SmoldynKeyword.front + " " + smoldynBct[2]);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.action + " " + SmoldynVCellMapper.SmoldynKeyword.all + " " + SmoldynVCellMapper.SmoldynKeyword.back + " " + smoldynBct[3]);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.color + " " + SmoldynVCellMapper.SmoldynKeyword.both + " 1 1 1");
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.polygon + " " + SmoldynVCellMapper.SmoldynKeyword.both + " " + SmoldynVCellMapper.SmoldynKeyword.edge);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.max_panels + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " 2");
// xz walls
switch(dimension) {
case 2:
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " +1 " + lowWall.getX() + " " + lowWall.getY() + " " + extent.getX());
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " -1 " + lowWall.getX() + " " + highWall.getY() + " " + extent.getX());
break;
case 3:
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " +1 " + lowWall.getX() + " " + lowWall.getY() + " " + lowWall.getZ() + " " + extent.getX() + " " + extent.getZ());
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " -1 " + lowWall.getX() + " " + highWall.getY() + " " + lowWall.getZ() + " " + extent.getX() + " " + extent.getZ());
break;
}
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.end_surface);
printWriter.println();
if (dimension > 2) {
// Z walls
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.start_surface + " " + VCellSmoldynKeyword.bounding_wall_surface_Z);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.action + " " + SmoldynVCellMapper.SmoldynKeyword.all + "(" + SmoldynVCellMapper.SmoldynKeyword.up + ") " + SmoldynVCellMapper.SmoldynKeyword.both + " " + SmoldynVCellMapper.SmoldynKeyword.reflect);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.action + " " + SmoldynVCellMapper.SmoldynKeyword.all + " " + SmoldynVCellMapper.SmoldynKeyword.front + " " + smoldynBct[4]);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.action + " " + SmoldynVCellMapper.SmoldynKeyword.all + " " + SmoldynVCellMapper.SmoldynKeyword.back + " " + smoldynBct[5]);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.color + " " + SmoldynVCellMapper.SmoldynKeyword.both + " 1 1 1");
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.polygon + " " + SmoldynVCellMapper.SmoldynKeyword.both + " " + SmoldynVCellMapper.SmoldynKeyword.edge);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.max_panels + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " 2");
// xy walls
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " +2 " + lowWall.getX() + " " + lowWall.getY() + " " + lowWall.getZ() + " " + extent.getX() + " " + extent.getY());
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.rect + " -2 " + lowWall.getX() + " " + lowWall.getY() + " " + highWall.getZ() + " " + extent.getX() + " " + extent.getY());
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.end_surface);
printWriter.println();
}
}
}
}
use of cbit.vcell.math.CompartmentSubDomain in project vcell by virtualcell.
the class SubdomainInfo method write.
public static void write(File file, MathDescription mathDesc) throws IOException, MathException {
PrintWriter pw = null;
try {
pw = new PrintWriter(new FileWriter(file));
pw.println("# " + VCML.CompartmentSubDomain + " name, handle");
pw.println("# " + VCML.MembraneSubDomain + " name, inside compartment name, handle, outside compartment name, handle");
Enumeration<SubDomain> subdomains = mathDesc.getSubDomains();
while (subdomains.hasMoreElements()) {
SubDomain sd = subdomains.nextElement();
if (sd instanceof CompartmentSubDomain) {
CompartmentSubDomain csd = (CompartmentSubDomain) sd;
pw.println(VCML.CompartmentSubDomain + ", " + csd.getName() + ", " + mathDesc.getHandle(csd));
} else if (sd instanceof MembraneSubDomain) {
MembraneSubDomain msd = (MembraneSubDomain) sd;
CompartmentSubDomain insideCompartment = msd.getInsideCompartment();
CompartmentSubDomain outsideCompartment = msd.getOutsideCompartment();
pw.println(VCML.MembraneSubDomain + ", " + msd.getName() + ", " + insideCompartment.getName() + ", " + mathDesc.getHandle(insideCompartment) + ", " + outsideCompartment.getName() + ", " + mathDesc.getHandle(outsideCompartment));
}
}
pw.close();
} finally {
if (pw != null) {
pw.close();
}
}
}
Aggregations