use of cbit.vcell.solver.SolverException in project vcell by virtualcell.
the class NFsimXMLWriter method getListOfSpecies.
private static Element getListOfSpecies(MathDescription mathDesc, SimulationSymbolTable simulationSymbolTable) throws SolverException {
CompartmentSubDomain compartmentSubDomain = (CompartmentSubDomain) mathDesc.getSubDomains().nextElement();
//
// NFsim expects a list of seed species. These are concrete species patterns that have a "ParticleProperties" element defined (for initial conditions).
//
Element listOfSpeciesElement = new Element("ListOfSpecies");
for (int speciesIndex = 0; speciesIndex < compartmentSubDomain.getParticleProperties().size(); speciesIndex++) {
// seedSpecies.getSpeciesPattern().resolveBonds();
ParticleProperties particleProperties = compartmentSubDomain.getParticleProperties().get(speciesIndex);
Element speciesElement = new Element("Species");
String speciesID = "S" + (speciesIndex + 1);
ParticleSpeciesPattern seedSpecies = (ParticleSpeciesPattern) particleProperties.getVariable();
speciesElement.setAttribute("id", speciesID);
speciesElement.setAttribute("name", seedSpecies.getName());
List<ParticleInitialCondition> particleInitialConditions = particleProperties.getParticleInitialConditions();
if (particleInitialConditions.size() != 1) {
throw new SolverException("multiple particle initial conditions not expected for " + ParticleSpeciesPattern.class.getSimpleName() + " " + seedSpecies.getName());
}
// the initial conditions must be a count in math (ParticleInitialConditionCount)
if (!(particleInitialConditions.get(0) instanceof ParticleInitialConditionCount)) {
throw new SolverException("expecting initial count for " + ParticleSpeciesPattern.class.getSimpleName() + " " + seedSpecies.getName());
}
ParticleInitialConditionCount initialCount = (ParticleInitialConditionCount) particleInitialConditions.get(0);
try {
double value = evaluateConstant(initialCount.getCount(), simulationSymbolTable);
Integer maxMoleculesPerType = simulationSymbolTable.getSimulation().getSolverTaskDescription().getNFSimSimulationOptions().getMaxMoleculesPerType();
if (maxMoleculesPerType == null) {
maxMoleculesPerType = NFsimSimulationOptions.DefaultMaxMoleculesPerSpecies;
}
if (maxMoleculesPerType.doubleValue() < value) {
String eMessage = "The Initial count for Species '" + seedSpecies.getName() + "' is " + BigDecimal.valueOf(value).toBigInteger();
eMessage += ", which is higher than the limit of " + maxMoleculesPerType + ".\n";
eMessage += "Please do one of the following: \n- reduce the Initial Condition value for this Species or reduce the compartment size\n";
eMessage += "- increase the maximal number of Molecules per Molecular Type in the Advanced Solver Options panel.";
throw new RuntimeException(eMessage);
}
speciesElement.setAttribute("concentration", Double.toString(value));
} catch (ExpressionException | MathException e) {
e.printStackTrace();
throw new SolverException("error processing initial count of " + ParticleSpeciesPattern.class.getSimpleName() + " " + seedSpecies.getName() + ": " + e.getMessage());
}
HashMap<Bond, BondSites> bondSiteMapping = new HashMap<Bond, BondSites>();
Element listOfMoleculesElement = getListOfMolecules(speciesID, seedSpecies, bondSiteMapping);
speciesElement.addContent(listOfMoleculesElement);
if (bondSiteMapping.size() > 0) {
Element listOfBondsElement = getListOfBonds(bondSiteMapping);
speciesElement.addContent(listOfBondsElement);
}
listOfSpeciesElement.addContent(speciesElement);
}
return listOfSpeciesElement;
}
use of cbit.vcell.solver.SolverException in project vcell by virtualcell.
the class NFsimXMLWriter method getListOfParameters.
private static Element getListOfParameters(MathDescription mathDesc, SimulationSymbolTable simulationSymbolTable) throws SolverException {
Element listOfParametersElement = new Element("ListOfParameters");
for (Variable var : simulationSymbolTable.getVariables()) {
Double value = null;
if (var instanceof Constant || var instanceof Function) {
Expression valExpression = var.getExpression();
Expression substitutedValExpr = null;
try {
substitutedValExpr = simulationSymbolTable.substituteFunctions(valExpression);
} catch (Exception e) {
e.printStackTrace(System.out);
throw new SolverException("Constant or Function " + var.getName() + " substitution failed : exp = \"" + var.getExpression().infix() + "\": " + e.getMessage());
}
try {
value = substitutedValExpr.evaluateConstant();
} catch (ExpressionException e) {
System.out.println("constant or function " + var.getName() + " = " + substitutedValExpr.infix() + " does not have a constant value");
}
Element parameterElement = new Element("Parameter");
parameterElement.setAttribute("id", var.getName());
if (value != null) {
parameterElement.setAttribute("type", "Constant");
parameterElement.setAttribute("value", value.toString());
} else {
// function, see getListOfFunctions() below
continue;
}
listOfParametersElement.addContent(parameterElement);
}
}
return listOfParametersElement;
}
use of cbit.vcell.solver.SolverException in project vcell by virtualcell.
the class SmoldynFileWriter method writeSurfaces.
private void writeSurfaces() throws SolverException, ImageException, PropertyVetoException, GeometryException, ExpressionException {
GeometrySurfaceDescription geometrySurfaceDescription = resampledGeometry.getGeometrySurfaceDescription();
SurfaceClass[] surfaceClasses = geometrySurfaceDescription.getSurfaceClasses();
GeometrySpec geometrySpec = resampledGeometry.getGeometrySpec();
SubVolume[] surfaceGeometrySubVolumes = geometrySpec.getSubVolumes();
GeometricRegion[] AllGeometricRegions = resampledGeometry.getGeometrySurfaceDescription().getGeometricRegions();
ArrayList<SurfaceGeometricRegion> surfaceRegionList = new ArrayList<SurfaceGeometricRegion>();
ArrayList<VolumeGeometricRegion> volumeRegionList = new ArrayList<VolumeGeometricRegion>();
for (GeometricRegion geometricRegion : AllGeometricRegions) {
if (geometricRegion instanceof SurfaceGeometricRegion) {
surfaceRegionList.add((SurfaceGeometricRegion) geometricRegion);
} else if (geometricRegion instanceof VolumeGeometricRegion) {
volumeRegionList.add((VolumeGeometricRegion) geometricRegion);
} else {
throw new SolverException("unsupported geometric region type " + geometricRegion.getClass());
}
}
printWriter.println("# geometry");
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.dim + " " + dimension);
if (bHasNoSurface) {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.max_compartment + " " + surfaceGeometrySubVolumes.length);
} else {
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.max_compartment + " " + (surfaceGeometrySubVolumes.length + 1));
// plus the surface which are bounding walls
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.max_surface + " " + (surfaceClasses.length + dimension));
}
printWriter.println();
// write boundaries and wall surfaces
writeWallSurfaces();
// for 3D ... smoldyn normal convension is triangle right-hand-rule normal points to the outside compartment subdomain.
if (!bHasNoSurface) {
membraneSubdomainTriangleMap = new HashMap<MembraneSubDomain, ArrayList<TrianglePanel>>();
// write surfaces
printWriter.println("# surfaces");
int triangleGlobalCount = 0;
int membraneIndex = -1;
SurfaceCollection surfaceCollection = geometrySurfaceDescription.getSurfaceCollection();
// pre-allocate collections used repeatedly in following loops; clear before reusing
HashMap<Node, Set<String>> nodeTriMap = new HashMap<>();
ArrayList<TrianglePanel> triList = new ArrayList<TrianglePanel>();
// use a sorted set to ensure neighbors written out is same order for reproducibility
SortedSet<String> neighborsForCurrentNode = new TreeSet<String>();
for (int sci = 0; sci < surfaceClasses.length; sci++) {
nodeTriMap.clear();
triList.clear();
int triLocalCount = 0;
SurfaceClass surfaceClass = surfaceClasses[sci];
GeometricRegion[] geometricRegions = geometrySurfaceDescription.getGeometricRegions(surfaceClass);
for (GeometricRegion gr : geometricRegions) {
SurfaceGeometricRegion sgr = (SurfaceGeometricRegion) gr;
VolumeGeometricRegion volRegion0 = (VolumeGeometricRegion) sgr.getAdjacentGeometricRegions()[0];
VolumeGeometricRegion volRegion1 = (VolumeGeometricRegion) sgr.getAdjacentGeometricRegions()[1];
SubVolume subVolume0 = volRegion0.getSubVolume();
SubVolume subVolume1 = volRegion1.getSubVolume();
CompartmentSubDomain compart0 = mathDesc.getCompartmentSubDomain(subVolume0.getName());
CompartmentSubDomain compart1 = mathDesc.getCompartmentSubDomain(subVolume1.getName());
MembraneSubDomain membraneSubDomain = mathDesc.getMembraneSubDomain(compart0, compart1);
if (membraneSubDomain == null) {
throw new SolverException(VCellErrorMessages.getSmoldynUnexpectedSurface(compart0, compart1));
}
int exteriorRegionID = volRegion0.getRegionID();
int interiorRegionID = volRegion1.getRegionID();
if (membraneSubDomain.getInsideCompartment() == compart0) {
exteriorRegionID = volRegion1.getRegionID();
interiorRegionID = volRegion0.getRegionID();
}
for (int j = 0; j < surfaceCollection.getSurfaceCount(); j++) {
Surface surface = surfaceCollection.getSurfaces(j);
if ((surface.getInteriorRegionIndex() == exteriorRegionID && surface.getExteriorRegionIndex() == interiorRegionID) || (surface.getInteriorRegionIndex() == interiorRegionID && surface.getExteriorRegionIndex() == exteriorRegionID)) {
// Polygon polygon = surface.getPolygons(k);
for (Polygon polygon : surface) {
if (polygonMembaneElementMap != null) {
membraneIndex = polygonMembaneElementMap.get(polygon).getMembraneIndex();
}
Node[] nodes = polygon.getNodes();
if (dimension == 2) {
// ignore z
Vect3d unitNormal = new Vect3d();
polygon.getUnitNormal(unitNormal);
unitNormal.set(unitNormal.getX(), unitNormal.getY(), 0);
int point0 = 0;
Vect3d v0 = new Vect3d(nodes[point0].getX(), nodes[point0].getY(), 0);
int point1 = 1;
Vect3d v1 = null;
for (point1 = 1; point1 < nodes.length; point1++) {
if (v0.getX() != nodes[point1].getX() || v0.getY() != nodes[point1].getY()) {
v1 = new Vect3d(nodes[point1].getX(), nodes[point1].getY(), 0);
break;
}
}
if (v1 == null) {
throw new RuntimeException("failed to generate surface");
}
Vect3d v01 = Vect3d.sub(v1, v0);
Vect3d unit01n = v01.cross(unitNormal);
unit01n.unit();
if (Math.abs(unit01n.getZ() - 1.0) < 1e-6) {
// v0 to v1 opposes vcell surface normal. it's already flipped.
Triangle triangle;
if (surface.getInteriorRegionIndex() == interiorRegionID) {
// we have to flipped it back
triangle = new Triangle(nodes[point1], nodes[point0], null);
} else {
triangle = new Triangle(nodes[point0], nodes[point1], null);
}
triList.add(new TrianglePanel(triLocalCount++, triangleGlobalCount++, membraneIndex, triangle));
} else if (Math.abs(unit01n.getZ() + 1.0) < 1e-6) {
// v0 to v1 is in direction of vcell surface normal.
Triangle triangle;
if (surface.getInteriorRegionIndex() == interiorRegionID) {
triangle = new Triangle(nodes[point0], nodes[point1], null);
} else {
triangle = new Triangle(nodes[point1], nodes[point0], null);
}
triList.add(new TrianglePanel(triLocalCount++, triangleGlobalCount++, membraneIndex, triangle));
} else {
throw new RuntimeException("failed to generate surface");
}
} else if (dimension == 3) {
Triangle triangle1;
Triangle triangle2;
if (surface.getInteriorRegionIndex() == interiorRegionID) {
// interior
triangle1 = new Triangle(nodes[0], nodes[1], nodes[2]);
triangle2 = new Triangle(nodes[0], nodes[2], nodes[3]);
} else {
triangle1 = new Triangle(nodes[2], nodes[1], nodes[0]);
triangle2 = new Triangle(nodes[3], nodes[2], nodes[0]);
}
triList.add(new TrianglePanel(triLocalCount++, triangleGlobalCount++, membraneIndex, triangle1));
triList.add(new TrianglePanel(triLocalCount++, triangleGlobalCount++, membraneIndex, triangle2));
}
}
}
}
}
// add triangles to node hash
for (TrianglePanel triPanel : triList) {
for (Node node : triPanel.triangle.getNodes()) {
if (node == null) {
continue;
}
Set<String> triNameSet = nodeTriMap.get(node);
if (triNameSet == null) {
triNameSet = new HashSet<String>();
nodeTriMap.put(node, triNameSet);
}
triNameSet.add(triPanel.name);
}
}
SubVolume[] adjacentSubvolums = surfaceClass.getAdjacentSubvolumes().toArray(new SubVolume[0]);
CompartmentSubDomain csd0 = simulation.getMathDescription().getCompartmentSubDomain(adjacentSubvolums[0].getName());
CompartmentSubDomain csd1 = simulation.getMathDescription().getCompartmentSubDomain(adjacentSubvolums[1].getName());
MembraneSubDomain membraneSubDomain = simulation.getMathDescription().getMembraneSubDomain(csd0, csd1);
membraneSubdomainTriangleMap.put(membraneSubDomain, triList);
final boolean initialMoleculesOnMembrane = (closestTriangles != null);
if (initialMoleculesOnMembrane) {
findClosestTriangles(membraneSubDomain, triList);
}
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.start_surface + " " + surfaceClass.getName());
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.action + " " + SmoldynVCellMapper.SmoldynKeyword.all + "(" + SmoldynVCellMapper.SmoldynKeyword.all + ") " + SmoldynVCellMapper.SmoldynKeyword.both + " " + SmoldynVCellMapper.SmoldynKeyword.reflect);
// printWriter.println(SmoldynKeyword.action + " " + SmoldynKeyword.all + "(" + SmoldynKeyword.up + ") " + SmoldynKeyword.both + " " + SmoldynKeyword.reflect);
// get color after species
Color c = colors[sci + particleVariableList.size()];
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.color + " " + SmoldynVCellMapper.SmoldynKeyword.both + " " + c.getRed() / 255.0 + " " + c.getGreen() / 255.0 + " " + c.getBlue() / 255.0 + " 0.1");
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.polygon + " " + SmoldynVCellMapper.SmoldynKeyword.front + " " + SmoldynVCellMapper.SmoldynKeyword.edge);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.polygon + " " + SmoldynVCellMapper.SmoldynKeyword.back + " " + SmoldynVCellMapper.SmoldynKeyword.edge);
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.max_panels + " " + SmoldynVCellMapper.SmoldynKeyword.tri + " " + triList.size());
for (TrianglePanel trianglePanel : triList) {
Triangle triangle = trianglePanel.triangle;
printWriter.print(SmoldynVCellMapper.SmoldynKeyword.panel + " " + SmoldynVCellMapper.SmoldynKeyword.tri);
switch(dimension) {
case 1:
printWriter.print(" " + triangle.getNodes(0).getX());
break;
case 2:
printWriter.print(" " + triangle.getNodes(0).getX() + " " + triangle.getNodes(0).getY());
printWriter.print(" " + triangle.getNodes(1).getX() + " " + triangle.getNodes(1).getY());
break;
case 3:
for (Node node : triangle.getNodes()) {
printWriter.print(" " + node.getX() + " " + node.getY() + " " + node.getZ());
}
break;
}
printWriter.println(" " + trianglePanel.name);
}
for (TrianglePanel triPanel : triList) {
neighborsForCurrentNode.clear();
for (Node node : triPanel.triangle.getNodes()) {
if (node == null) {
continue;
}
neighborsForCurrentNode.addAll(nodeTriMap.get(node));
}
neighborsForCurrentNode.remove(triPanel.name);
// printWriter.print(SmoldynKeyword.neighbors + " " +triPanel.name);
// to allow smoldyn read line length as 256, chop the neighbors to multiple lines
int maxNeighborCount = 4;
//
int count = 0;
for (String neigh : neighborsForCurrentNode) {
if (count % maxNeighborCount == 0) {
printWriter.println();
printWriter.print(SmoldynVCellMapper.SmoldynKeyword.neighbors + " " + triPanel.name);
}
printWriter.print(" " + neigh);
count++;
}
}
printWriter.println();
printWriter.println(SmoldynVCellMapper.SmoldynKeyword.end_surface);
printWriter.println();
}
// write compartment
// printWriter.println("# bounding wall compartment");
// printWriter.println(SmoldynKeyword.start_compartment + " " + VCellSmoldynKeyword.bounding_wall_compartment);
// printWriter.println(SmoldynKeyword.surface + " " + VCellSmoldynKeyword.bounding_wall_surface_X);
// if (dimension > 1) {
// printWriter.println(SmoldynKeyword.surface + " " + VCellSmoldynKeyword.bounding_wall_surface_Y);
// if (dimension > 2) {
// printWriter.println(SmoldynKeyword.surface + " " + VCellSmoldynKeyword.bounding_wall_surface_Z);
// }
// }
// printWriter.println(SmoldynKeyword.end_compartment);
// printWriter.println();
}
}
use of cbit.vcell.solver.SolverException in project vcell by virtualcell.
the class SmoldynFileWriter method init.
private void init() throws SolverException {
simulation = simTask.getSimulation();
mathDesc = simulation.getMathDescription();
simulationSymbolTable = simTask.getSimulationJob().getSimulationSymbolTable();
particleVariableList = new ArrayList<ParticleVariable>();
Variable[] variables = simulationSymbolTable.getVariables();
for (Variable variable : variables) {
if (variable instanceof ParticleVariable) {
if (variable.getDomain() == null) {
throw new SolverException("Particle Variables are required to be defined in a subdomain using syntax Subdomain::Variable.");
}
particleVariableList.add((ParticleVariable) variable);
}
}
// write geometry
Geometry geometry = mathDesc.getGeometry();
dimension = geometry.getDimension();
try {
// clone and resample geometry
resampledGeometry = (Geometry) BeanUtils.cloneSerializable(geometry);
GeometrySurfaceDescription geoSurfaceDesc = resampledGeometry.getGeometrySurfaceDescription();
ISize newSize = simulation.getMeshSpecification().getSamplingSize();
geoSurfaceDesc.setVolumeSampleSize(newSize);
geoSurfaceDesc.updateAll();
bHasNoSurface = geoSurfaceDesc.getSurfaceClasses() == null || geoSurfaceDesc.getSurfaceClasses().length == 0;
} catch (Exception e) {
e.printStackTrace();
throw new SolverException(e.getMessage());
}
if (!bGraphicOpenGL) {
writeMeshFile();
}
colors = ColorUtil.generateAutoColor(particleVariableList.size() + resampledGeometry.getGeometrySurfaceDescription().getSurfaceClasses().length, bg, new Integer(5));
}
use of cbit.vcell.solver.SolverException in project vcell by virtualcell.
the class SmoldynFileWriter method writeHighResVolumeSamples.
private void writeHighResVolumeSamples() throws SolverException {
try {
printWriter.println("# HighResVolumeSamples");
printWriter.println(VCellSmoldynKeyword.start_highResVolumeSamples);
Origin origin = resampledGeometry.getOrigin();
Extent extent = resampledGeometry.getExtent();
int numSamples = 10000000;
ISize sampleSize = GeometrySpec.calulateResetSamplingSize(3, extent, numSamples);
VCImage vcImage = RayCaster.sampleGeometry(resampledGeometry, sampleSize, true);
printWriter.println(VCellSmoldynKeyword.Origin + " " + origin.getX() + " " + origin.getY() + " " + origin.getZ());
printWriter.println(VCellSmoldynKeyword.Size + " " + extent.getX() + " " + extent.getY() + " " + extent.getZ());
printWriter.println(VCellSmoldynKeyword.CompartmentHighResPixelMap + " " + resampledGeometry.getGeometrySpec().getNumSubVolumes());
VCPixelClass[] pixelclasses = vcImage.getPixelClasses();
if (pixelclasses != null && resampledGeometry.getGeometrySpec().getSubVolumes() != null && pixelclasses.length != resampledGeometry.getGeometrySpec().getSubVolumes().length) {
throw new SolverException("Fast mesh sampling failed. Found " + pixelclasses.length + " of " + resampledGeometry.getGeometrySpec().getSubVolumes().length + " volume domains.\n");
}
for (SubVolume subVolume : resampledGeometry.getGeometrySpec().getSubVolumes()) {
for (VCPixelClass vcPixelClass : pixelclasses) {
if (vcPixelClass.getPixel() == subVolume.getHandle()) {
printWriter.println(subVolume.getName() + " " + vcPixelClass.getPixel());
break;
}
}
}
printWriter.println(VCellSmoldynKeyword.VolumeSamples + " " + sampleSize.getX() + " " + sampleSize.getY() + " " + sampleSize.getZ());
if (vcImage != null) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DeflaterOutputStream dos = new DeflaterOutputStream(bos);
byte[] pixels = vcImage.getPixels();
dos.write(pixels, 0, pixels.length);
dos.close();
byte[] compressedPixels = bos.toByteArray();
String compressedStr = Hex.toString(compressedPixels);
int strchar = 250;
int length = compressedStr.length();
for (int i = 0; i < Math.ceil(length * 1.0 / strchar); ++i) {
printWriter.println(compressedStr.substring(i * strchar, Math.min(length, (i + 1) * strchar)));
}
}
printWriter.println(VCellSmoldynKeyword.end_highResVolumeSamples);
printWriter.println();
} catch (Exception ex) {
ex.printStackTrace(System.out);
throw new RuntimeException("Error writing High Resolution Volume Samples: " + ex.getMessage());
}
}
Aggregations