def getValue = value
}
- private class PositionIndex(name: String, value: Expression[IntType]) extends SpatialIndex {
+ private class PositionIndex(name: String, value: Expression[IntType], centre: Expression[IntType]) extends FunctionSpatialIndex {
def getName = name
def getValue = value
+ def getFunctionCentre = centre
}
def apply(basisName: String, dataName: String) : PPDFunctionSet = {
val numSpheres = basis % FunctionBasis.num
val ppdWidths = for(dim <- 0 to 2) yield CellInfo.public % CellInfo.ppdWidth(dim)
- val cellWidthInPPDs = for(dim <- 0 to 2) yield CellInfo.public % CellInfo.numPPDs(dim)
+ val cellWidthPPDs = for(dim <- 0 to 2) yield CellInfo.public % CellInfo.numPPDs(dim)
+ val cellWidthPts = for(dim <- 0 to 2) yield cellWidthPPDs(dim) * ppdWidths(dim)
val producer = new ProducerStatement
val sphereIndex = producer.addIteration("sphere_index", 1, numSpheres)
val ppdGlobalCount = (~(sphere % Sphere.ppdList)).readAt(ppdIndex, 1) - 1
// The integer co-ordinates of the PPD (0-based)
- val a3pos = producer.addExpression("ppd_pos1", ppdGlobalCount / (cellWidthInPPDs(0)*cellWidthInPPDs(1)))
- val a2pos = producer.addExpression("ppd_pos2", (ppdGlobalCount % (cellWidthInPPDs(0)*cellWidthInPPDs(1)))/cellWidthInPPDs(0))
- val a1pos = producer.addExpression("ppd_pos3", ppdGlobalCount % cellWidthInPPDs(0))
+ val a3pos = producer.addExpression("ppd_pos1", ppdGlobalCount / (cellWidthPPDs(0)*cellWidthPPDs(1)))
+ val a2pos = producer.addExpression("ppd_pos2", (ppdGlobalCount % (cellWidthPPDs(0)*cellWidthPPDs(1)))/cellWidthPPDs(0))
+ val a1pos = producer.addExpression("ppd_pos3", ppdGlobalCount % cellWidthPPDs(0))
val ppdPos = List(a1pos, a2pos, a3pos)
val tightbox = (~(basis % FunctionBasis.tightBoxes)).readAt(sphereIndex)
// The offsets into the PPDs for the edges of the tightbox
- val ppdStartOffsets = for(dim <- 0 to 2) yield tightbox % TightBox.startPts(dim)
- val ppdFinishOffsets = for(dim <- 0 to 2) yield tightbox % TightBox.finishPts(dim)
+ val ppdStartOffsets = for(dim <- 0 to 2) yield tightbox % TightBox.startPts(dim) - 1
+ val ppdFinishOffsets = for(dim <- 0 to 2) yield tightbox % TightBox.finishPts(dim) - 1
// The first and last PPDs in PPD co-ordinates (0-based, inside simulation cell)
val startPPDs = for(dim <- 0 to 2) yield
- producer.addExpression("start_ppd"+(dim+1), (tightbox % TightBox.startPPD(dim) + cellWidthInPPDs(dim)-1) % cellWidthInPPDs(dim))
+ producer.addExpression("start_ppd"+(dim+1), (tightbox % TightBox.startPPD(dim) + cellWidthPPDs(dim)-1) % cellWidthPPDs(dim))
val finishPPDs = for(dim <- 0 to 2) yield
- producer.addExpression("finish_ppd"+(dim+1),(tightbox % TightBox.finishPPD(dim) + cellWidthInPPDs(dim)-1) % cellWidthInPPDs(dim))
+ producer.addExpression("finish_ppd"+(dim+1),(tightbox % TightBox.finishPPD(dim) + cellWidthPPDs(dim)-1) % cellWidthPPDs(dim))
+
+ // The dimensions of the tightbox
+ val tightboxStartPts = for(dim <- 0 to 2) yield
+ producer.addExpression("tightbox_start_pt"+(dim+1), startPPDs(dim)*(CellInfo.public % CellInfo.ppdWidth(dim)) + ppdStartOffsets(dim))
+
+ val tightboxFinishPts = for(dim <- 0 to 2) yield
+ producer.addExpression("tightbox_finsh_pt"+(dim+1), finishPPDs(dim)*(CellInfo.public % CellInfo.ppdWidth(dim)) + ppdFinishOffsets(dim))
+
+ val tightboxWidth = for(dim <- 0 to 2) yield
+ producer.addExpression("tightbox_width_pt"+(dim+1), (tightboxFinishPts(dim) - tightboxStartPts(dim) + cellWidthPts(dim)) % cellWidthPts(dim))
+
+ val tightboxCentre = for(dim <- 0 to 2) yield
+ producer.addExpression("tightbox_centre_pt"+(dim+1), ((tightboxStartPts(dim) : Expression[IntType]) + tightboxWidth(dim) / 2) % cellWidthPts(dim))
// Offsets for the current PPD being iterated over
val loopStarts = for(dim <- 0 to 2) yield
- producer.addExpression("start_pt"+(dim+1), new ConditionalValue[IntType](startPPDs(dim) |==| ppdPos(dim), ppdStartOffsets(dim), 1))
+ producer.addExpression("start_pt"+(dim+1), new ConditionalValue[IntType](startPPDs(dim) |==| ppdPos(dim), ppdStartOffsets(dim), 0))
val loopEnds = for(dim <- 0 to 2) yield
- producer.addExpression("end_pt"+(dim+1), new ConditionalValue[IntType](finishPPDs(dim) |==| ppdPos(dim), ppdFinishOffsets(dim), ppdWidths(dim)))
+ producer.addExpression("end_pt"+(dim+1), new ConditionalValue[IntType](finishPPDs(dim) |==| ppdPos(dim), ppdFinishOffsets(dim), ppdWidths(dim) - 1))
// Loops for iterating over the PPD itself
val ppdIndices = for(dim <- 0 to 2) yield producer.addIteration("point"+(dim+1), loopStarts(dim), loopEnds(dim))
val positions = for(dim <- 0 to 2) yield
producer.addExpression("pos"+(dim+1), ppdPos(dim)*ppdWidths(dim) + ppdIndices(dim))
- // TODO: We explicitly convert to Expression[IntType] here since we don't promote both sides of the addition for ppdDataIndex.
- val ppdDataStart : Expression[IntType] =
+ val ppdDataStart =
producer.addExpression("ppd_data_start", (sphere % Sphere.offset) + (ppdIndex-1) * (CellInfo.public % CellInfo.pointsInPPD))
- val ppdDataIndex = producer.addExpression("ppd_data_index", ppdDataStart
- + (ppdIndices(2)-1) * (CellInfo.public % CellInfo.ppdWidth(1)) * (CellInfo.public % CellInfo.ppdWidth(0))
- + (ppdIndices(1)-1) * (CellInfo.public % CellInfo.ppdWidth(0))
- + (ppdIndices(0)-1))
+ val ppdDataIndex = producer.addExpression("ppd_data_index", (ppdDataStart: Expression[IntType])
+ + ppdIndices(2) * (CellInfo.public % CellInfo.ppdWidth(1)) * (CellInfo.public % CellInfo.ppdWidth(0))
+ + ppdIndices(1) * (CellInfo.public % CellInfo.ppdWidth(0))
+ + ppdIndices(0))
val dataValue = producer.addExpression("data", data.readAt(ppdDataIndex))
val discreteIndices = List[DiscreteIndex](new SphereIndex("sphere", sphereIndex))
- val spatialIndices = {for ((name, index) <- List[String]("x", "y", "z") zip positions) yield new PositionIndex(name, index)}
+ val spatialIndices = {
+ val indexNames = List("x", "y", "z")
+ for (dim <- 0 to 2) yield new PositionIndex(indexNames(dim), positions(dim), tightboxCentre(dim))
+ }
new PPDFunctionSet(discreteIndices, spatialIndices, dataValue, producer)
}