TEST(BoundingBox, Intersection){
	Point lb(1,2,0);
	Point ub(2,4,0);
	BoundingBox bb1(lb, ub);
	BoundingBox bb2(lb, ub);

	// Intersection should return an bounding box equal to bb2 and bb1,
	// they are the same bb
	BoundingBox bbIntersection = bb2.intersection(bb1);
	EXPECT_TRUE( bbIntersection.getLb().getX() == bb2.getLb().getX() &&
				bbIntersection.getLb().getY() == bb2.getLb().getY() &&
				bbIntersection.getLb().getZ() == bb2.getLb().getZ());

	EXPECT_TRUE( bbIntersection.getUb().getX() == bb2.getUb().getX() &&
				bbIntersection.getUb().getY() == bb2.getUb().getY() &&
				bbIntersection.getUb().getZ() == bb2.getUb().getZ());

	Point lb3(2,3,0);
	Point ub3(2,4,0);
	BoundingBox bb3(lb3, ub3);
	bbIntersection = bb2.intersection(bb3);
	// lower bound is the value of of bb3
	EXPECT_TRUE( bbIntersection.getLb().getX() == lb3.getX() &&
				bbIntersection.getLb().getY() == lb3.getY() &&
				bbIntersection.getLb().getZ() == lb3.getZ());

	// upper bound should not change
	EXPECT_TRUE( bbIntersection.getUb().getX() == bb2.getUb().getX() &&
				bbIntersection.getUb().getY() == bb2.getUb().getY() &&
				bbIntersection.getUb().getZ() == bb2.getUb().getZ());

}
示例#2
0
void meta_service::on_update_configuration(dsn_message_t req)
{
    if (!_started)
    {
        configuration_update_response response;
        response.err = ERR_SERVICE_NOT_ACTIVE;
        reply(req, response);
        return;
    }

    if (!_failure_detector->is_primary())
    {
        dsn_rpc_forward(req, _failure_detector->get_primary().c_addr());
        return;
    }

    if (_state->freezed())
    {
        configuration_update_request request;
        configuration_update_response response;
        
        ::unmarshall(req, request);

        response.err = ERR_STATE_FREEZED;
        _state->query_configuration_by_gpid(request.config.gpid, response.config);

        reply(req, response);
        return;
    }

    void* ptr;
    size_t sz;
    dsn_msg_read_next(req, &ptr, &sz);
    dsn_msg_read_commit(req, 0); // commit 0 so we can read again

    uint64_t offset;
    int len = (int)sz + sizeof(int32_t);
    
    char* buffer = new char[len];
    *(int32_t*)buffer = (int)sz;
    memcpy(buffer + sizeof(int32_t), ptr, sz);

    auto tmp = std::shared_ptr<char>(buffer);
    blob bb2(tmp, 0, len);

    auto request = std::shared_ptr<configuration_update_request>(new configuration_update_request());
    ::unmarshall(req, *request);

    {

        zauto_lock l(_log_lock);
        offset = _offset;
        _offset += len;

        file::write(_log, buffer, len, offset, LPC_CM_LOG_UPDATE, this,
            std::bind(&meta_service::on_log_completed, this, 
            std::placeholders::_1, std::placeholders::_2, bb2, request, dsn_msg_create_response(req)));
    }
}
示例#3
0
int main() {
  
  dump();

  for (int i=0;i<500;i++) {
    {
      flop = !flop;
      blockWipedPool().wipe();
      if (i%10==0)  blockWipedPool().clear();
      BP b1(new A1);
      BP b2(new A2);
      BP b3(new A3);
      dump();
      {
	BP bb1(b1->clone());
	BP bb2(b2->clone());
	BP bb3(b3->clone());
	dump();
      }
      dump("after clone destr");
      
      BP b11(new A1);
      BP b22(new A2);
      BP b23(new A2);
      dump();
      b1.reset();
      b2.reset();
      b3.reset();
      dump("after first destr");
    }
    dump();
    { 
      std::vector<BP> v(233);
      for_each(v.begin(),v.end(),&gen);
      dump("after 233 alloc");
      v.resize(123);
      dump("after 110 distr");
    }
    dump();
    
    for (int i=0;i<3;i++){
      std::vector<BP> v(2432);
      for_each(v.begin(),v.end(),&gen);
      std::vector<BP> v1(3213);
      for_each(v1.begin(),v1.end(),&gen);
      {
	std::vector<BP> d; d.swap(v);
      }
      // alloc disalloc
      std::vector<BP> vs(514);
      for_each(vs.begin(),vs.end(),&gen);
      for_each(vs.begin(),vs.end(),&gen);
    }
    dump("loop end");
  }
  return 0;
}
示例#4
0
int main() {
  
  dump();


  {
    BP b1(new A1);
    BP b2(new A2);
    dump();
    {
      BP bb1(b1->clone());
      BP bb2(b2->clone());
      dump();
    }
    dump("after clone destr");

    BP b11(new A1);
    BP b22(new A2);
    dump();
    b1.reset();
    b2.reset();
    dump("after first destr");
  }

  dump();
  { 
    std::vector<BP> v(233);
    for_each(v.begin(),v.end(),&gen);
    dump("after 233 alloc");
    v.resize(123);
    dump("after 110 distr");
  }
  dump();

  for (int i=0;i<100;i++){
    std::vector<BP> v(2432);
    for_each(v.begin(),v.end(),&gen);
    std::vector<BP> v1(3213);
    for_each(v1.begin(),v1.end(),&gen);
    {
      std::vector<BP> d; d.swap(v);
    }
    // alloc disalloc
    std::vector<BP> vs(514);
    for_each(vs.begin(),vs.end(),&gen);
    for_each(vs.begin(),vs.end(),&gen);
  }

  return 0;
}
示例#5
0
ImplicitFuncCSG::ImplicitFuncCSG(const BBox<scalar,3>& bb,OP_TYPE op):_alpha(0.8f),_op(op)
{
    BBox<scalar,2> bb2(bb._minC.block(0,0,2,1),bb._maxC.block(0,0,2,1));
    boost::shared_ptr<ImplicitFuncCSG> axis01(new ImplicitFuncCSG(bb2,op));
    boost::shared_ptr<ImplicitFuncCSG> axis2(new ImplicitFuncCSG(op));
    if(op == INTERSECT) {
        axis2->_a.reset(new ImplicitFuncPlane(Vec3(0.0f,0.0f,bb._minC.z()),Vec3(0.0f,0.0f,-1.0f)));
        axis2->_b.reset(new ImplicitFuncPlane(Vec3(0.0f,0.0f,bb._maxC.z()),Vec3(0.0f,0.0f, 1.0f)));
    } else {
        axis2->_a.reset(new ImplicitFuncPlane(Vec3(0.0f,0.0f,bb._minC.z()),Vec3(0.0f,0.0f, 1.0f)));
        axis2->_b.reset(new ImplicitFuncPlane(Vec3(0.0f,0.0f,bb._maxC.z()),Vec3(0.0f,0.0f,-1.0f)));
    }
    _a=axis01;
    _b=axis2;
}
TEST(BoundingBox, NoIntersection){
	Point lb(1,2,0), ub(2,4,0), lb2(3,5,0), ub2(4,6,0);
	BoundingBox bb1(lb, ub);
	BoundingBox bb2(lb2, ub2);

	// Intersection should return an bounding box equal to bb2 and bb1,
	// they are the same bb
	BoundingBox bbInter = bb2.intersection(bb1);
	EXPECT_FALSE( bb1.doesIntersect(bb2));

	// Lower bound of intersection should contain greater values
	// among lower bound of both bounding boxes (lb2)
	EXPECT_TRUE( bbInter.getLb().getX() == lb2.getX() &&
				bbInter.getLb().getY() == lb2.getY() &&
				bbInter.getLb().getZ() == lb2.getZ());

	// Upper bound of intersection should contain smaller values
	// among upper bound of both bounding boxes (ub)
	EXPECT_TRUE( bbInter.getUb().getX() == ub.getX() &&
				bbInter.getUb().getY() == ub.getY() &&
				bbInter.getUb().getZ() == ub.getZ());

}
示例#7
0
bool
GenericEllipse::isIntersectedBy(
    const GenericEllipse* e,
    SegmentPointVector& isecPoints,
    int& isecCount) const
{
    isecCount = 0;

    // Circle (Ellipse 1 scaled on y axis):
    //     (I)  (x - m1.x)^2 + (y - m1.y)^2 = r^2
    //     (II) x^2 + y^2 = r^2  --> moved to origin
    // Ellipse 2:
    //     (I)  (x - m2.x)^2 / a^2 + (y - m2.y)^2 / b^2 = 1
    //     (II) (x - (m2.x - m1.x))^2 / a^2 + (y - (m2.y - m1.y))^2 / b^2 = 1
    //           --> moved by the same vector as circle/ellipse 1

    // A scale factor that transform the first ellipse into a circle in order to
    // simplify calculation.
    // For the calculation, make ellipse 1's vertical radius equal to the
    // horizontal one such that we have a circle, and scale the coordinate
    // system accordingly
    Point2D scale(1.f, radius_.x / radius_.y);
    Point2D m1 = center_ * scale;
    Point2D r1 = radius_ * scale;
    Point2D m2 = e->center_ * scale;
    Point2D r2 = e->radius_ * scale;

    geom::GenericRect bb1(m1 - r1, m1 + r1);
    geom::GenericRect bb2(m2 - r2, m2 + r2);

    // The rectangle enclosing the area in which the intersection point(s) is
    // (are) located
    GenericRect searchRect;
    if (!bb1.isIntersectedByRect(bb2, searchRect))
    {
        return false;
    }

    // Translate whole coordinate system so ellipse (circle) 1's center is at
    // origin to simplify our calculation; don't forget to re-translate later.
    // Ellipse 2 is now: (x - c)^2 / a^2 + (y - d)^2 / b^2 = 1
    double c = m2.x - m1.x;
    double d = m2.y - m1.y;

    double a_squ = r2.x * r2.x;
    double b_squ = r2.y * r2.y;
    double b_squ_div_a_squ = b_squ / a_squ;
    double r_squ = r1.x * r1.x;
    double d_squ = d*d;

    // P = b^2 / a^2 - 1
    double pp = b_squ_div_a_squ - 1.;
    // Q = -2 * b^2 / a^2 * c
    double qq = -2. * b_squ_div_a_squ * c;
    // R = r^2 + d^2 - b^2 + b^2 / a^2 *c^2
    double rr = r_squ + d_squ - b_squ + b_squ_div_a_squ * (c*c);

    double qq_squ = qq*qq;

    // Formula:
    // 0 =
    // (P^2)x^4 + (2PQ)x^3 + (Q^2 + 2PR + 4d^2)x^2 + (2QR)x + R^2 - 4(d^2)(r^2)

    // alpha = P^2
    double alpha = pp*pp;
    // beta = 2PQ
    double beta = 2. * pp * qq;
    // gamma = Q^2 + 2PR + 4d^2
    double gamma = qq_squ + (2. * pp * rr) + (4. * d_squ);
    // delta = 2QR
    double delta = 2. * qq * rr;
    // epsilon = R^2 - 4(d^2)(r^2)
    double epsilon = (rr*rr) - (4. * d_squ * r_squ);

    // Now solve alpha*x^4 + beta*x^3 + gamma*x^2 + delta*x + epsilon = 0
    double roots[4];
    int numRoots;
    quarticPolynomialRoots(alpha, beta, gamma, delta, epsilon, roots, numRoots);


    float fx[4], fy[4];
    for (int i = 0; i != numRoots; ++i)
    {
        // Rescale and retranslate y to normal coordinate system
        // y = sqrt(r^2 - x^2)
        fy[i] = (std::sqrt(r_squ - roots[i] * roots[i]) + m1.y) / scale.y;
        fx[i] = roots[i] + m1.x;
    }

    // Handle identical ellipses case
    if ((center_ == e->center_) && (radius_ == e->radius_))
    {
        numRoots = 1;
        fx[0] = center_.x;
        fy[0] = center_.y + radius_.y;
    }
    // Handle symmetric case where every x corresponds to two roots (x, +-y).
    // For some cases (two circles intersecting only, it seems), only one or two
    // roots will be found by solving the polynomial, so we have to add the
    // missing roots.
    else if ((center_.y == e->center_.y) && ((numRoots == 1) || (numRoots == 2)))
    {
        std::cout << "numroots "<< numRoots << std::endl;
        for (int i = 0; i != numRoots; ++i)
        {
            fx[i + numRoots] = fx[i];
            fy[i + numRoots] = 2. * center_.y - fy[i];
        }
        numRoots *= 2;
    }
    else
    {
        // Check if points are valid; for those that are not, we assume that
        // their y coordinate is on the wrong side of the x axis, so mirror it
        // along that axis. If the point is invalid in general,
        // makeSegmentPoint() will finally fail (see below).
        for (int i = 0; i != numRoots; ++i)
        {
            Point2D p(fx[i], fy[i]);
            if (!e->isIntersectedByPoint(p))
            {
                fy[i] = 2. * center_.y - fy[i];
            }
        }
    }

    for (int i = 0; i != numRoots; ++i)
    {
        Point2D p(fx[i], fy[i]);
        SegmentPoint* s = makeSegmentPoint(p, e->getQuadrant(p));
        isecPoints.push_back(s);
        ++isecCount;
    }

    return isecCount;
}
示例#8
0
;}bbu bb2193(bbx*bb298){bbd bb368;bb4 bb18=bb541(bb298,17 ,&bb368);bb2
((bb18)==bb98)&&bb823(bb298,bb368+bb12(bb415),bb2022,bb12(bb2022));}
示例#9
0
bbf bb2022[8 ]={0 };bbu bb2135(bbx*bb298){bbd bb368;bb4 bb18=bb541(
bb298,17 ,&bb368);bb2((bb18)==bb98)&&bb536(bb298)==bb368+bb12(bb415)+1
;}bbu bb2193(bbx*bb298){bbd bb368;bb4 bb18=bb541(bb298,17 ,&bb368);bb2
void
run_test(Cost_Map &map, Point &start, Point &goal, vector<int> &times) {
	struct timeval pre;
	struct timeval post;

///	printf("UCS\n");
	UCS ucs(&map, start, goal);
	gettimeofday(&pre, NULL); 
	Path path = ucs.search();
	gettimeofday(&post, NULL); 
	double reference_cost = path.length;
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

///	printf("A*\n");
	Manhattan Manhattan(&map, start, goal);
	gettimeofday(&pre, NULL); 
	path = Manhattan.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

///	printf("A*\n");
	Euclidean euclidean(&map, start, goal);
	gettimeofday(&pre, NULL); 
	path = euclidean.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

///	printf("A*\n");
	Octile octile(&map, start, goal);
	gettimeofday(&pre, NULL); 
	path = octile.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

///	printf("Coarse single\n");
	CUCS_Heuristic cucs(&map, start, goal);
	gettimeofday(&pre, NULL); 
	path = cucs.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

///	printf("BB\n");
	Boundaries_Blocking bb2(&map, start, goal, 2, xscale, yscale);
	gettimeofday(&pre, NULL); 
	path = bb2.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

	Boundaries_Blocking bb(&map, start, goal, levels, xscale, yscale);
	gettimeofday(&pre, NULL); 
	path = bb.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

///	printf("BN\n");
	Boundaries_NonBlocking bnb2(&map, start, goal, 2, xscale, yscale);
	gettimeofday(&pre, NULL); 
	path = bnb2.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

	Boundaries_NonBlocking bnb(&map, start, goal, levels, xscale, yscale);
	gettimeofday(&pre, NULL); 
	path = bnb.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

///	printf("CB\n");
	Corners_Blocking cb2(&map, start, goal, 2, xscale, yscale);
	gettimeofday(&pre, NULL); 
	path = cb2.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

	Corners_Blocking cb(&map, start, goal, levels, xscale, yscale);
	gettimeofday(&pre, NULL); 
	path = cb.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

///	printf("CN\n");
	Corners_NonBlocking cnb2(&map, start, goal, 2, xscale, yscale);
	gettimeofday(&pre, NULL); 
	path = cnb2.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);

	Corners_NonBlocking cnb(&map, start, goal, levels, xscale, yscale);
	gettimeofday(&pre, NULL); 
	path = cnb.search();
	gettimeofday(&post, NULL); 
	check_and_update(start, goal, pre, post, reference_cost, path.length, times);
}
示例#11
0
int main(int argc, char *argv[])
{
  Pooma::initialize(argc, argv);
  Pooma::Tester tester(argc, argv);

  // To declare a field, you first need to set up a layout. This requires
  // knowing the physical vertex-domain and the number of external guard
  // cell layers. Vertex domains contain enough points to hold all of the
  // rectilinear centerings that POOMA is likely to support for quite
  // awhile. Also, it means that the same layout can be used for all
  // fields, regardless of centering.
  
  Interval<2> physicalVertexDomain(14, 14);
  Loc<2> blocks(3, 3);
  GridLayout<2> layout1(physicalVertexDomain, blocks, GuardLayers<2>(1),
                        LayoutTag_t());
  GridLayout<2> layout0(physicalVertexDomain, blocks, GuardLayers<2>(0),
                        LayoutTag_t());

  Centering<2> cell = canonicalCentering<2>(CellType, Continuous, AllDim);
  Centering<2> vert = canonicalCentering<2>(VertexType, Continuous, AllDim);
  Centering<2> yedge = canonicalCentering<2>(EdgeType, Continuous, YDim);

  Vector<2> origin(0.0);
  Vector<2> spacings(1.0, 2.0);

  // First basic test verifies that we're assigning to the correct areas
  // on a brick.

  typedef
    Field<UniformRectilinearMesh<2>, double,
    MultiPatch<GridTag, BrickTag_t> > Field_t;
  Field_t b0(cell, layout1, origin, spacings);
  Field_t b1(vert, layout1, origin, spacings);
  Field_t b2(yedge, layout1, origin, spacings);
  Field_t b3(yedge, layout1, origin, spacings);
  Field_t bb0(cell, layout0, origin, spacings);
  Field_t bb1(vert, layout0, origin, spacings);
  Field_t bb2(yedge, layout0, origin, spacings);

  b0.all() = 0.0;
  b1.all() = 0.0;
  b2.all() = 0.0;

  b0 = 1.0;
  b1 = 1.0;
  b2 = 1.0;

  bb0.all() = 0.0;
  bb1.all() = 0.0;
  bb2.all() = 0.0;

  bb0 = 1.0;
  bb1 = 1.0;
  bb2 = 1.0;

  // SPMD code follows.
  // Note, SPMD code will work with the evaluator if you are careful
  // to perform assignment on all the relevant contexts.  The patchLocal
  // function creates a brick on the local context, so you can just perform
  // the assignment on that context.

  int i;

  for (i = 0; i < b0.numPatchesLocal(); ++i)
  {
    Patch<Field_t>::Type_t patch = b0.patchLocal(i);
    //    tester.out() << "context " << Pooma::context() << ":  assigning to patch " << i
    //              << " with domain " << patch.domain() << std::endl;
    patch += 1.5;
  }

  // This is safe to do since b1 and b2 are built with the same layout.
  for (i = 0; i < b1.numPatchesLocal(); ++i)
  {
    b1.patchLocal(i) += 1.5;
    b2.patchLocal(i) += 1.5;
  }

  for (i = 0; i < bb0.numPatchesLocal(); ++i)
  {
    Patch<Field_t>::Type_t patch = bb0.patchLocal(i);
    //    tester.out() << "context " << Pooma::context() << ":  assigning to patch on bb0 " << i
    //              << " with domain " << patch.domain() << std::endl;
    patch += 1.5;
  }

  // This is safe to do since bb1 and bb2 are built with the same layout.
  for (i = 0; i < bb1.numPatchesLocal(); ++i)
  {
    bb1.patchLocal(i) += 1.5;
    bb2.patchLocal(i) += 1.5;
  }

  tester.check("cell centered field is 2.5", all(b0 == 2.5));
  tester.check("vert centered field is 2.5", all(b1 == 2.5));
  tester.check("edge centered field is 2.5", all(b2 == 2.5));

  tester.out() << "b0.all():" << std::endl << b0.all() << std::endl;
  tester.out() << "b1.all():" << std::endl << b1.all() << std::endl;
  tester.out() << "b2.all():" << std::endl << b2.all() << std::endl;

  tester.check("didn't write into b0 boundary",
               sum(b0.all()) == 2.5 * b0.physicalDomain().size());
  tester.check("didn't write into b1 boundary",
               sum(b1.all()) == 2.5 * b1.physicalDomain().size());
  tester.check("didn't write into b2 boundary",
               sum(b2.all()) == 2.5 * b2.physicalDomain().size());

  tester.check("cell centered field is 2.5", all(bb0 == 2.5));
  tester.check("vert centered field is 2.5", all(bb1 == 2.5));
  tester.check("edge centered field is 2.5", all(bb2 == 2.5));

  tester.out() << "bb0:" << std::endl << bb0 << std::endl;
  tester.out() << "bb1:" << std::endl << bb1 << std::endl;
  tester.out() << "bb2:" << std::endl << bb2 << std::endl;

  typedef
    Field<UniformRectilinearMesh<2>, double,
    MultiPatch<GridTag, CompressibleBrickTag_t> > CField_t;
  CField_t c0(cell, layout1, origin, spacings);
  CField_t c1(vert, layout1, origin, spacings);
  CField_t c2(yedge, layout1, origin, spacings);
  CField_t cb0(cell, layout0, origin, spacings);
  CField_t cb1(vert, layout0, origin, spacings);
  CField_t cb2(yedge, layout0, origin, spacings);

  c0.all() = 0.0;
  c1.all() = 0.0;
  c2.all() = 0.0;

  c0 = 1.0;
  c1 = 1.0;
  c2 = 1.0;

  cb0.all() = 0.0;
  cb1.all() = 0.0;
  cb2.all() = 0.0;

  cb0 = 1.0;
  cb1 = 1.0;
  cb2 = 1.0;

  // SPMD code follows.
  // Note, SPMD code will work with the evaluator if you are careful
  // to perform assignment on all the relevant contexts.  The patchLocal
  // function creates a brick on the local context, so you can just perform
  // the assignment on that context.

  for (i = 0; i < c0.numPatchesLocal(); ++i)
  {
    Patch<CField_t>::Type_t patch = c0.patchLocal(i);
    tester.out() << "context " << Pooma::context() << ":  assigning to patch " << i
                 << " with domain " << patch.domain() << std::endl;
    patch += 1.5;
  }

  // This is safe to do since c1 and c2 are built with the same layout.
  for (i = 0; i < c1.numPatchesLocal(); ++i)
  {
    c1.patchLocal(i) += 1.5;
    c2.patchLocal(i) += 1.5;
  }

  for (i = 0; i < cb0.numPatchesLocal(); ++i)
  {
    Patch<CField_t>::Type_t patch = cb0.patchLocal(i);
    tester.out() << "context " << Pooma::context() << ":  assigning to patch on cb0 " << i
                 << " with domain " << patch.domain() << std::endl;
    patch += 1.5;
  }

  // This is safe to do since cb1 and cb2 are cuilt with the same layout.
  for (i = 0; i < cb1.numPatchesLocal(); ++i)
  {
    cb1.patchLocal(i) += 1.5;
    cb2.patchLocal(i) += 1.5;
  }

  tester.check("cell centered field is 2.5", all(c0 == 2.5));
  tester.check("vert centered field is 2.5", all(c1 == 2.5));
  tester.check("edge centered field is 2.5", all(c2 == 2.5));

  tester.out() << "c0.all():" << std::endl << c0.all() << std::endl;
  tester.out() << "c1.all():" << std::endl << c1.all() << std::endl;
  tester.out() << "c2.all():" << std::endl << c2.all() << std::endl;

  tester.check("didn't write into c0 boundary",
               sum(c0.all()) == 2.5 * c0.physicalDomain().size());
  tester.check("didn't write into c1 boundary",
               sum(c1.all()) == 2.5 * c1.physicalDomain().size());
  tester.check("didn't write into c2 boundary",
               sum(c2.all()) == 2.5 * c2.physicalDomain().size());

  tester.check("cell centered field is 2.5", all(cb0 == 2.5));
  tester.check("vert centered field is 2.5", all(cb1 == 2.5));
  tester.check("edge centered field is 2.5", all(cb2 == 2.5));

  tester.out() << "cb0:" << std::endl << cb0 << std::endl;
  tester.out() << "cb1:" << std::endl << cb1 << std::endl;
  tester.out() << "cb2:" << std::endl << cb2 << std::endl;

  //------------------------------------------------------------------
  // Scalar code example:
  //

  c0 = iota(c0.domain()).comp(0);
  c1 = iota(c1.domain()).comp(1);

  // Make sure all the data-parallel are done:

  Pooma::blockAndEvaluate();

  for (i = 0; i < c0.numPatchesLocal(); ++i)
  {
    Patch<CField_t>::Type_t local0 = c0.patchLocal(i);
    Patch<CField_t>::Type_t local1 = c1.patchLocal(i);
    Patch<CField_t>::Type_t local2 = c2.patchLocal(i);

    Interval<2> domain = local2.domain();  // physical domain of local y-edges

    // --------------------------------------------------------------
    // I believe the following is probably the most efficient approach
    // for sparse computations.  For data-parallel computations, the
    // evaluator will uncompress the patches and take brick views, which
    // provide the most efficient access.  If you are only performing
    // the computation on a small portion of cells, then the gains would
    // be outweighed by the act of copying the compressed value to all the
    // cells.
    //
    // The read function is used on the right hand side, because
    // operator() is forced to uncompress the patch just in case you want
    // to write to it.

    for(Interval<2>::iterator pos = domain.begin(); pos != domain.end(); ++pos)
    {
      Loc<2> edge = *pos;
      Loc<2> rightCell = edge;  // cell to right is same cell
      Loc<2> leftCell = edge - Loc<2>(1,0);
      Loc<2> topVert = edge + Loc<2>(0, 1);
      Loc<2> bottomVert = edge;

      local2(edge) =
        local0.read(rightCell) + local0.read(leftCell) +
        local1.read(topVert) + local1.read(bottomVert);
    }

    // This statement is optional, it tries to compress the patch after
    // we're done computing on it.  Since I used .read() for the local0 and 1
    // they remained in their original state. compress() can be expensive, so
    // it may not be worth trying unless space is really important.

    compress(local2);
  }

  tester.out() << "c0" << std::endl << c0 << std::endl;
  tester.out() << "c1" << std::endl << c1 << std::endl;
  tester.out() << "c2" << std::endl << c2 << std::endl;

  //------------------------------------------------------------------
  // Interfacing with a c-function:
  //
  // This example handles the corner cases, where the patches from a
  // cell centered field with no guard layers actually contain some
  // extra data.

  Pooma::blockAndEvaluate();

  for (i = 0; i < cb0.numPatchesLocal(); ++i)
  {
    Patch<CField_t>::Type_t local0 = cb0.patchLocal(i);
    Interval<2> physicalDomain = local0.physicalDomain();
    double *data;
    int size = physicalDomain.size();

    if (physicalDomain == local0.totalDomain())
    {
      uncompress(local0);
      data = &local0(physicalDomain.firsts());
      nonsense(data, size);
    }
    else
    {
      // In this case, the engine has extra storage even though the
      // field has the right domain. We copy it to a brick engine,
      // call the function and copy it back.  No uncompress is required,
      // since the assignment will copy the compressed value into the
      // brick.

      // arrayView is a work-around.  Array = Field doesn't work at
      // the moment.

      Array<2, double, Brick> brick(physicalDomain);
      Array<2, double, CompressibleBrick> arrayView(local0.engine());
      brick = arrayView(physicalDomain);
      Pooma::blockAndEvaluate();
      data = &brick(Loc<2>(0));
      nonsense(data, size);
      arrayView(physicalDomain) = brick;

      // Note that we don't need a blockAndEvaluate here, since an iterate has
      // been spawned to perform the copy.
    }

    // If you want to try compress(local0) here, you should do blockAndEvaluate
    // first in case the local0 = brick hasn't been executed yet.
  }
      
  tester.out() << "cb0.all()" << std::endl << cb0 << std::endl;

  b2 = positions(b2).comp(0);

  RefCountedBlockPtr<double> block = pack(b2);

  // The following functions give you access to the raw data from pack.
  // Note that the lifetime of the data is managed by the RefCountedBlockPtr,
  // so when "block" goes out of scope, the data goes away.  (i.e. Don't write
  // a function where you return block.beginPointer().)

  double *start = block.beginPointer();  // start of the data
  double *end = block.endPointer();      // one past the end
  int size = block.size();               // size of the data

  tester.out() << Pooma::context() << ":" << block.size() << std::endl;

  unpack(b3, block);

  tester.out() << "b2" << std::endl << b2 << std::endl;
  tester.out() << "b3" << std::endl << b3 << std::endl;

  tester.check("pack, unpack", all(b2 == b3));

  int ret = tester.results("LocalPatch");
  Pooma::finalize();
  return ret;
}