private void loop() {
   float max = 0;
   int counter = 0;
   while (nodes.size() != 0) {
     Point2DInteger n = nodes.peek();
     ArrayList<Point2DInteger> children = FlowDirectionUtils.getUpstreamNodes(n, flowDirection);
     if (children.size() == 0) {
       flowAccumulation.set(n.getX(), n.getY(), 0);
       nodes.pop();
     } else {
       float sum = 0;
       boolean hasUndefined = false;
       for (Point2DInteger p : children) {
         float acc = flowAccumulation.get(p.getX(), p.getY());
         if (Float.isNaN(acc)) {
           hasUndefined = true;
           nodes.add(p);
         } else {
           sum += acc;
           sum += getArea(p);
         }
       }
       if (!hasUndefined) {
         max = Math.max(max, sum);
         flowAccumulation.set(n.getX(), n.getY(), sum);
         nodes.pop();
       }
     }
     counter++;
     if ((counter & 0xffff) == 0xffff) {
       System.out.println("FlowAcc " + counter + " " + max);
     }
   }
   System.out.println("Done");
 }
 private void clearFlowAccumulation() {
   for (Rectangle2DInteger rect : this.range) {
     int x0 = rect.getX();
     int y0 = rect.getY();
     int w = rect.getWidth();
     int h = rect.getHeight();
     int x1 = x0 + w;
     int y1 = y0 + h;
     for (int y = y0; y < y1; y++) {
       for (int x = x0; x < x1; x++) {
         flowAccumulation.set(x, y, Float.NaN);
       }
     }
   }
 }
 public float get(final int x, final int y) {
   Coord4D c = getCoordinates(x, y);
   FloatGridWritable tile = elements[c.xx][c.yy];
   return tile != null ? tile.get(c.x, c.y) : Float.NaN;
 }