void TestNonlinearEquationPde()
    {
        ChastePoint<1> zero1(0);
        ChastePoint<2> zero2(0,0);
        ChastePoint<3> zero3(0,0,0);
        double u = 2.0;

        NonlinearEquationPde<1> heat_equation1;
        NonlinearEquationPde<2> heat_equation2;
        NonlinearEquationPde<3> heat_equation3;

        TS_ASSERT_DELTA(heat_equation1.ComputeNonlinearSourceTerm(zero1,u),0.0,1e-12);
        TS_ASSERT_DELTA(heat_equation2.ComputeNonlinearSourceTerm(zero2,u),0.0,1e-12);
        TS_ASSERT_DELTA(heat_equation3.ComputeNonlinearSourceTerm(zero3,u),0.0,1e-12);

        // Diffusion matrices should be equal to identity * u;
        c_matrix<double, 1, 1> diff1 = heat_equation1.ComputeDiffusionTerm(zero1,u);
        c_matrix<double, 2, 2> diff2 = heat_equation2.ComputeDiffusionTerm(zero2,u);
        c_matrix<double, 3, 3> diff3 = heat_equation3.ComputeDiffusionTerm(zero3,u);

        TS_ASSERT_DELTA(diff1(0,0),u,1e-12);

        TS_ASSERT_DELTA(diff2(0,0),u,1e-12);
        TS_ASSERT_DELTA(diff2(1,1),u,1e-12);
        TS_ASSERT_DELTA(diff2(0,1),0,1e-12);

        TS_ASSERT_DELTA(diff3(0,0),u,1e-12);
        TS_ASSERT_DELTA(diff3(1,1),u,1e-12);
        TS_ASSERT_DELTA(diff3(2,2),u,1e-12);
        TS_ASSERT_DELTA(diff3(0,1),0,1e-12);
        TS_ASSERT_DELTA(diff3(0,2),0,1e-12);
        TS_ASSERT_DELTA(diff3(1,2),0,1e-12);
    }
  ExecStatus
  ReEq<View0,View1>::propagate(Space& home, const ModEventDelta&) {
    if (b.one())
      GECODE_REWRITE(*this,(Eq<View0,View1>::post(home(*this),x0,x1)));
    if (b.zero())
      GECODE_REWRITE(*this,(Distinct<View0,View1>::post(home(*this),x0,x1)));

    if (x0.assigned() && x1.assigned()) {
      // directly test x0==x1
      GlbRanges<View0> x0lb(x0);
      GlbRanges<View1> x1lb(x1);
      for (; x0lb() && x1lb(); ++x0lb, ++x1lb) {
        if (x0lb.min() != x1lb.min() ||
            x0lb.max() != x1lb.max()) {
          GECODE_ME_CHECK(b.zero_none(home));
          return home.ES_SUBSUMED(*this);
        }
      }
      if (!x0lb() && !x1lb()) {
        GECODE_ME_CHECK(b.one_none(home));
        return home.ES_SUBSUMED(*this);
      } else {
        GECODE_ME_CHECK(b.zero_none(home));
        return home.ES_SUBSUMED(*this);
      }
    }

    // check whether cardinalities still allow equality
    if (x0.cardMin() > x1.cardMax() ||
        x1.cardMin() > x0.cardMax()) {
      GECODE_ME_CHECK(b.zero_none(home));
      return home.ES_SUBSUMED(*this);
    }

    // check glb(x0) subset lub(x1)
    GlbRanges<View0> x0lb(x0);
    LubRanges<View1> x1ub(x1);
    Iter::Ranges::Diff<GlbRanges<View0>, LubRanges<View1> > diff1(x0lb, x1ub);
    if ( diff1() ) {
      GECODE_ME_CHECK(b.zero_none(home));
      return home.ES_SUBSUMED(*this);
    }

    // check glb(x1) subset lub(x0)
    GlbRanges<View1> x1lb(x1);
    LubRanges<View0> x0ub(x0);
    Iter::Ranges::Diff<GlbRanges<View1>, LubRanges<View0> > diff2(x1lb, x0ub);
    if ( diff2() ) {
      GECODE_ME_CHECK(b.zero_none(home));
      return home.ES_SUBSUMED(*this);
    }

    return ES_FIX;
  }
Beispiel #3
0
int main ()
{
	REAL res;
	REAL tol = 1E-5;
	//Testing central diff
	printf("Central diff\n");
	res = diff(1, *x1);
	assert(is_equal(1, res, tol));
	printf("%.8f \n", res);
	res = diff(1, *x3x2);
	assert(is_equal(5, res, tol));
	printf("%.8f \n", res);
	
	//Testing forward diff
	printf("Forward diff\n");
	res = diff_forward(1, x1(1), *x1);
	assert(is_equal(1, res, tol));
	printf("%.8f \n", res);
	res = diff_forward(1, x3x2(1), *x3x2);
	assert(is_equal(5, res, tol));
	printf("%.8f \n", res);

	//Testing backward diff
	printf("Backward diff\n");
	res = diff_backward(1, 1, *x1);
	assert(is_equal(1, res, tol));
	printf("%.8f \n", res);
	res = diff_backward(1, 2, *x3x2);
	assert(is_equal(5, res, tol));
	printf("%.8f \n", res);

	//Testing central diff2
	printf("Central diff2\n");
	res = diff2(1, 1, *x1);
	assert(is_equal(0, res, tol));
	printf("%.8f \n", res);
	res = diff2(1, 2, *x3x2);
	assert(is_equal(8.0, res, 0.01));
	printf("%.8f \n", res);

	//Testing PNRB
	printf("Root by PNRB\n");
	res = PNRB(1513123.131533, *x1_0001);
	assert(is_equal(1E-4, res, tol));
	printf("%.8f \n", res);
	res = PNRB(1514563.123124, *x2_0025);
	assert(is_equal(0.0005, res, tol));
	printf("%.8f \n", res);

	return 0;
}
Beispiel #4
0
KDevelop::VcsJob* KDevSvnPlugin::diff(const QUrl &fileOrDirectory,
                                      const KDevelop::VcsRevision& srcRevision,
                                      const KDevelop::VcsRevision& dstRevision,
                                      KDevelop::VcsDiff::Type diffType,
                                      KDevelop::IBasicVersionControl::RecursionMode recurse)
{
    KDevelop::VcsLocation loc(fileOrDirectory);
    return diff2(loc, loc, srcRevision, dstRevision, diffType, recurse);
}
Beispiel #5
0
void
CMathGeom3D::
FaceNormal(const CPoint3D &point1, const CPoint3D &point2,
           const CPoint3D &point3, CNPlane3D &normal)
{
  CVector3D diff1(point1, point2);
  CVector3D diff2(point2, point3);

  normal.setDirection(CVector3D::crossProduct(diff1, diff2));

  normal.setScalar(CVector3D::dotProduct(normal.getDirection(), point1.x, point1.y, point1.z));
}
Beispiel #6
0
void
CMathGeom3D::
FaceNormal(double x1, double y1, double z1, double x2, double y2, double z2,
           double x3, double y3, double z3, CNPlane3D &normal)
{
  CVector3D diff1(x2 - x1, y2 - y1, z2 - z1);
  CVector3D diff2(x3 - x2, y3 - y2, z3 - z2);

  normal.setDirection(CVector3D::crossProduct(diff1, diff2));

  normal.setScalar(CVector3D::dotProduct(normal.getDirection(), x1, y1, z1));
}
    void TestHeatEquation()
    {
        ChastePoint<1> zero1(0);
        ChastePoint<2> zero2(0,0);
        ChastePoint<3> zero3(0,0,0);
        double u = 2.0;

        HeatEquation<1> pde1;
        HeatEquation<2> pde2;
        HeatEquation<3> pde3;

        TS_ASSERT_DELTA(pde1.ComputeSourceTerm(zero1,u), 0.0, 1e-12);
        TS_ASSERT_DELTA(pde2.ComputeSourceTerm(zero2,u), 0.0, 1e-12);
        TS_ASSERT_DELTA(pde3.ComputeSourceTerm(zero3,u), 0.0, 1e-12);

        TS_ASSERT_DELTA(pde1.ComputeDuDtCoefficientFunction(zero1), 1.0, 1e-12);
        TS_ASSERT_DELTA(pde2.ComputeDuDtCoefficientFunction(zero2), 1.0, 1e-12);
        TS_ASSERT_DELTA(pde3.ComputeDuDtCoefficientFunction(zero3), 1.0, 1e-12);

        // Diffusion matrices should be equal to identity
        c_matrix<double, 1, 1> diff1 = pde1.ComputeDiffusionTerm(zero1);
        c_matrix<double, 2, 2> diff2 = pde2.ComputeDiffusionTerm(zero2);
        c_matrix<double, 3, 3> diff3 = pde3.ComputeDiffusionTerm(zero3);

        TS_ASSERT_DELTA(diff1(0,0), 1, 1e-12);

        TS_ASSERT_DELTA(diff2(0,0), 1, 1e-12);
        TS_ASSERT_DELTA(diff2(1,1), 1, 1e-12);
        TS_ASSERT_DELTA(diff2(0,1), 0, 1e-12);

        TS_ASSERT_DELTA(diff3(0,0), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(1,1), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(2,2), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(0,1), 0, 1e-12);
        TS_ASSERT_DELTA(diff3(0,2), 0, 1e-12);
        TS_ASSERT_DELTA(diff3(1,2), 0, 1e-12);

        Node<1> node(0, zero1);
        TS_ASSERT_DELTA(pde1.ComputeSourceTermAtNode(node,u), 0.0, 1e-12);
    }
Beispiel #8
0
void csWaterDemo::generateNormals ()
{
  csVector3 *vbuf = gFactState->GetVertices ();
  csVector3 *nbuf = gFactState->GetNormals ();
  csColor *cbuf = gFactState->GetColors ();
  csTriangle *ibuf = gFactState->GetTriangles ();

  int numVerts = gFactState->GetVertexCount ();
  int numTris = gFactState->GetTriangleCount ();
  int i;

  //zeroout the normals
  for(i=0;i<numVerts;i++)
  {
    nbuf[i] = csVector3(0,0,0);
  }

  //accumulate facenormals
  for(i=0;i<numTris;i++)
  {
    int a, b, c;
    a=ibuf[i].a;
    b=ibuf[i].b;
    c=ibuf[i].c;

    csVector3 v0(vbuf[a]);
    csVector3 v1(vbuf[b]);
    csVector3 v2(vbuf[c]);
    csVector3 diff1 (v2-v1);
    csVector3 diff2 (v0-v1);
    csVector3 n = diff1 % diff2;
    nbuf[a] += n;
    nbuf[b] += n;
    nbuf[c] += n;
  }

  //normalize
  for(i=0;i<numVerts;i++)
  {
    nbuf[i].Normalize ();
    cbuf[i].red = nbuf[i].x;
    cbuf[i].green = nbuf[i].y;
    cbuf[i].blue = nbuf[i].z;
  }
}
Beispiel #9
0
  ExecStatus
  ElementUnion<SView,RView>::propagate(Space& home, const ModEventDelta&) {
    Region r(home);
    int n = iv.size();

    bool loopVar;
    do {
      loopVar = false;

      // Cache the upper bound iterator, as we have to
      // modify the upper bound while iterating
      LubRanges<RView> x1ub(x1);
      Iter::Ranges::Cache<LubRanges<RView> > x1ubc(r,x1ub);
      Iter::Ranges::ToValues<Iter::Ranges::Cache<LubRanges<RView> > >
        vx1ub(x1ubc);

      GlbRanges<RView> x1lb(x1);
      Iter::Ranges::Cache<GlbRanges<RView> > x1lbc(r,x1lb);
      Iter::Ranges::ToValues<Iter::Ranges::Cache<GlbRanges<RView> > >
        vx1(x1lbc);

      // In the first iteration, compute in before[i] the union
      // of all the upper bounds of the x_i. At the same time,
      // exclude inconsistent x_i from x1 and remove them from
      // the list, cancel their dependencies.

      GLBndSet sofarBefore(home);
      LUBndSet selectedInter(home, IntSet (Limits::min,
                                   Limits::max));
      GLBndSet* before =
        static_cast<GLBndSet*>(r.ralloc(sizeof(GLBndSet)*n));

      int j = 0;
      int i = 0;

      unsigned int maxCard = 0;
      unsigned int minCard = Limits::card;

      while ( vx1ub() ) {

        // Remove vars at indices not in the upper bound
        if (iv[i].idx < vx1ub.val()) {
          iv[i].view.cancel(home,*this, PC_SET_ANY);
          ++i;
          continue;
        }
        assert(iv[i].idx == vx1ub.val());
        iv[j] = iv[i];

        SView candidate = iv[j].view;
        int candidateInd = iv[j].idx;

        // inter = glb(candidate) & complement(lub(x0))
        GlbRanges<SView> candlb(candidate);
        LubRanges<SView> x0ub(x0);
        Iter::Ranges::Diff<GlbRanges<SView>,
          LubRanges<SView> > diff(candlb, x0ub);

        bool selectSingleInconsistent = false;
        if (x1.cardMax() <= 1) {
          GlbRanges<SView> x0lb(x0);
          LubRanges<SView> candub(candidate);
          Iter::Ranges::Diff<GlbRanges<SView>,
                             LubRanges<SView> > diff2(x0lb, candub);
          selectSingleInconsistent = diff2() || candidate.cardMax() < x0.cardMin();
        }

        // exclude inconsistent x_i
        // an x_i is inconsistent if
        //  * at most one x_i can be selected and there are
        //    elements in x_0 that can't be in x_i
        //    (selectSingleInconsistent)
        //  * its min cardinality is greater than maxCard of x0
        //  * inter is not empty (there are elements in x_i
        //    that can't be in x_0)
        if (selectSingleInconsistent ||
            candidate.cardMin() > x0.cardMax() ||
            diff()) {
          ModEvent me = (x1.exclude(home,candidateInd));
          loopVar |= me_modified(me);
          GECODE_ME_CHECK(me);

          iv[j].view.cancel(home,*this, PC_SET_ANY);
          ++i;
          ++vx1ub;
          continue;
        } else {
          // if x_i is consistent, check whether we know
          // that its index is in x1
          if (vx1() && vx1.val()==candidateInd) {
            // x0 >= candidate, candidate <= x0
            GlbRanges<SView> candlb(candidate);
            ModEvent me = x0.includeI(home,candlb);
            loopVar |= me_modified(me);
            GECODE_ME_CHECK(me);

            LubRanges<SView> x0ub(x0);
            me = candidate.intersectI(home,x0ub);
            loopVar |= me_modified(me);
            GECODE_ME_CHECK(me);
            ++vx1;
          }
          new (&before[j]) GLBndSet(home);
          before[j].update(home,sofarBefore);
          LubRanges<SView> cub(candidate);
          sofarBefore.includeI(home,cub);
          GlbRanges<SView> clb(candidate);
          selectedInter.intersectI(home,clb);
          maxCard = std::max(maxCard, candidate.cardMax());
          minCard = std::min(minCard, candidate.cardMin());
        }

        ++vx1ub;
        ++i; ++j;
      }

      // cancel the variables with index greater than
      // max of lub(x1)
      for (int k=i; k<n; k++) {
        iv[k].view.cancel(home,*this, PC_SET_ANY);
      }
      n = j;
      iv.size(n);

      if (x1.cardMax()==0) {
        // Selector is empty, hence the result must be empty
        {
          GECODE_ME_CHECK(x0.cardMax(home,0));
        }
        for (int i=n; i--;)
          before[i].dispose(home);
        return home.ES_SUBSUMED(*this);
      }

      if (x1.cardMin() > 0) {
        // Selector is not empty, hence the intersection of the
        // possibly selected lower bounds is contained in x0
        BndSetRanges si(selectedInter);
        ModEvent me = x0.includeI(home, si);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
        me = x0.cardMin(home, minCard);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
      }
      selectedInter.dispose(home);

      if (x1.cardMax() <= 1) {
        ModEvent me = x0.cardMax(home, maxCard);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
      }

      {
        // x0 <= sofarBefore
        BndSetRanges sfB(sofarBefore);
        ModEvent me = x0.intersectI(home,sfB);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
      }

      sofarBefore.dispose(home);

      GLBndSet sofarAfter(home);

      // In the second iteration, this time backwards, compute
      // sofarAfter as the union of all lub(x_j) with j>i
      for (int i=n; i--;) {
        // TODO: check for size of universe here?
        // if (sofarAfter.size() == 0) break;

        // extra = inter(before[i], sofarAfter) - lub(x0)
        BndSetRanges b(before[i]);
        BndSetRanges s(sofarAfter);
        GlbRanges<SView> x0lb(x0);
        Iter::Ranges::Union<BndSetRanges, BndSetRanges> inter(b,s);
        Iter::Ranges::Diff<GlbRanges<SView>,
          Iter::Ranges::Union<BndSetRanges,BndSetRanges> > diff(x0lb, inter);
        if (diff()) {
          ModEvent me = (x1.include(home,iv[i].idx));
          loopVar |= me_modified(me);
          GECODE_ME_CHECK(me);

          // candidate != extra
          me = iv[i].view.includeI(home,diff);
          loopVar |= me_modified(me);
          GECODE_ME_CHECK(me);
        }

        LubRanges<SView> iviub(iv[i].view);
        sofarAfter.includeI(home,iviub);
        before[i].dispose(home);
      }
      sofarAfter.dispose(home);

    } while (loopVar);

    // Test whether we determined x1 without determining x0
    if (x1.assigned() && !x0.assigned()) {
      int ubsize = static_cast<int>(x1.lubSize());
      if (ubsize > 2) {
        assert(ubsize==n);
        ViewArray<SView> is(home,ubsize);
        for (int i=n; i--;)
          is[i]=iv[i].view;
        GECODE_REWRITE(*this,(RelOp::UnionN<SView, SView>
                        ::post(home(*this),is,x0)));
      } else if (ubsize == 2) {
        assert(n==2);
        SView a = iv[0].view;
        SView b = iv[1].view;
        GECODE_REWRITE(*this,(RelOp::Union<SView, SView, SView>
                       ::post(home(*this),a,b,x0)));
      } else if (ubsize == 1) {
        assert(n==1);
        GECODE_REWRITE(*this,(Rel::Eq<SView,SView>::post(home(*this),x0,iv[0].view)));
      } else {
        GECODE_ME_CHECK(x0.cardMax(home, 0));
        return home.ES_SUBSUMED(*this);
      }
    }

    bool allAssigned = true;
    for (int i=iv.size(); i--;) {
      if (!iv[i].view.assigned()) {
        allAssigned = false;
        break;
      }
    }
    if (x0.assigned() && x1.assigned() && allAssigned) {
      return home.ES_SUBSUMED(*this);
    }

    return ES_FIX;
  }
Beispiel #10
0
TEST(WorldDiff, SetWorld)
{
  collision_detection::WorldPtr world1(new collision_detection::World);
  collision_detection::WorldPtr world2(new collision_detection::World);
  collision_detection::WorldDiff diff1(world1);
  collision_detection::WorldDiff diff1b(world1);
  collision_detection::WorldDiff diff2(world2);
  collision_detection::WorldDiff::const_iterator it;

  shapes::ShapePtr ball(new shapes::Sphere(1.0));
  shapes::ShapePtr box(new shapes::Box(1,2,3));
  shapes::ShapePtr cyl(new shapes::Cylinder(4,5));

  world1->addToObject("objA1",
                    ball,
                    Eigen::Affine3d::Identity());

  world1->addToObject("objA2",
                    ball,
                    Eigen::Affine3d::Identity());

  world1->addToObject("objA3",
                    ball,
                    Eigen::Affine3d::Identity());

  world2->addToObject("objB1",
                    box,
                    Eigen::Affine3d::Identity());

  world2->addToObject("objB2",
                    box,
                    Eigen::Affine3d::Identity());

  world2->addToObject("objB3",
                    box,
                    Eigen::Affine3d::Identity());

  EXPECT_EQ(3, diff1.getChanges().size());
  EXPECT_EQ(3, diff1b.getChanges().size());
  EXPECT_EQ(3, diff2.getChanges().size());

  diff1b.clearChanges();

  EXPECT_EQ(3, diff1.getChanges().size());
  EXPECT_EQ(0, diff1b.getChanges().size());
  EXPECT_EQ(3, diff2.getChanges().size());


  diff1.setWorld(world2);

  EXPECT_EQ(6, diff1.getChanges().size());
  EXPECT_EQ(0, diff1b.getChanges().size());
  EXPECT_EQ(3, diff2.getChanges().size());

  it = diff1.getChanges().find("objA1");
  EXPECT_NE(diff1.end(), it);
  EXPECT_EQ(collision_detection::World::DESTROY,
            it->second);

  it = diff1.getChanges().find("objA2");
  EXPECT_NE(diff1.end(), it);
  EXPECT_EQ(collision_detection::World::DESTROY,
            it->second);

  it = diff1.getChanges().find("objA2");
  EXPECT_NE(diff1.end(), it);
  EXPECT_EQ(collision_detection::World::DESTROY,
            it->second);

  it = diff1.getChanges().find("objB1");
  EXPECT_NE(diff1.end(), it);
  EXPECT_EQ(collision_detection::World::CREATE |
            collision_detection::World::ADD_SHAPE,
            it->second);

  it = diff1.getChanges().find("objB2");
  EXPECT_NE(diff1.end(), it);
  EXPECT_EQ(collision_detection::World::CREATE |
            collision_detection::World::ADD_SHAPE,
            it->second);

  it = diff1.getChanges().find("objB3");
  EXPECT_NE(diff1.end(), it);
  EXPECT_EQ(collision_detection::World::CREATE |
            collision_detection::World::ADD_SHAPE,
            it->second);




  diff1b.setWorld(world2);

  EXPECT_EQ(6, diff1.getChanges().size());
  EXPECT_EQ(6, diff1b.getChanges().size());
  EXPECT_EQ(3, diff2.getChanges().size());

  it = diff1b.getChanges().find("objA1");
  EXPECT_NE(diff1b.end(), it);
  EXPECT_EQ(collision_detection::World::DESTROY,
            it->second);

  it = diff1b.getChanges().find("objA2");
  EXPECT_NE(diff1b.end(), it);
  EXPECT_EQ(collision_detection::World::DESTROY,
            it->second);

  it = diff1b.getChanges().find("objA2");
  EXPECT_NE(diff1b.end(), it);
  EXPECT_EQ(collision_detection::World::DESTROY,
            it->second);

  it = diff1b.getChanges().find("objB1");
  EXPECT_NE(diff1b.end(), it);
  EXPECT_EQ(collision_detection::World::CREATE |
            collision_detection::World::ADD_SHAPE,
            it->second);

  it = diff1b.getChanges().find("objB2");
  EXPECT_NE(diff1b.end(), it);
  EXPECT_EQ(collision_detection::World::CREATE |
            collision_detection::World::ADD_SHAPE,
            it->second);

  it = diff1b.getChanges().find("objB3");
  EXPECT_NE(diff1b.end(), it);
  EXPECT_EQ(collision_detection::World::CREATE |
            collision_detection::World::ADD_SHAPE,
            it->second);






  world1->addToObject("objC",
                    box,
                    Eigen::Affine3d::Identity());

  EXPECT_EQ(6, diff1.getChanges().size());
  EXPECT_EQ(6, diff1b.getChanges().size());
  EXPECT_EQ(3, diff2.getChanges().size());


  world2->addToObject("objC",
                    box,
                    Eigen::Affine3d::Identity());


  EXPECT_EQ(7, diff1.getChanges().size());
  EXPECT_EQ(7, diff1b.getChanges().size());
  EXPECT_EQ(4, diff2.getChanges().size());


  diff2.setWorld(world1);

  EXPECT_EQ(7, diff1.getChanges().size());
  EXPECT_EQ(7, diff1b.getChanges().size());
  EXPECT_EQ(7, diff2.getChanges().size());

  it = diff2.getChanges().find("objC");
  EXPECT_NE(diff2.end(), it);
  EXPECT_EQ(collision_detection::World::CREATE |
            collision_detection::World::ADD_SHAPE |
            collision_detection::World::DESTROY,
            it->second);




  world1->addToObject("objD",
                    box,
                    Eigen::Affine3d::Identity());

  EXPECT_EQ(7, diff1.getChanges().size());
  EXPECT_EQ(7, diff1b.getChanges().size());
  EXPECT_EQ(8, diff2.getChanges().size());

  world2->addToObject("objE",
                    box,
                    Eigen::Affine3d::Identity());

  EXPECT_EQ(8, diff1.getChanges().size());
  EXPECT_EQ(8, diff1b.getChanges().size());
  EXPECT_EQ(8, diff2.getChanges().size());

}
Beispiel #11
0
    void TestHeatEquationWithElementDependentSourceTerm()
    {
        // The PDE is set to give elements with index = 0 a source of zero
        // and a source of 1 otherwise.

        std::vector<Node<1>*> one_d_nodes;
        one_d_nodes.push_back(new Node<1>(0, false, 2.0));
        one_d_nodes.push_back(new Node<1>(1, false, 2.5));
        Element<1,1> one_d_element(0u, one_d_nodes);
        ChastePoint<1> zero1(0);

        std::vector<Node<2>*> two_d_nodes;
        two_d_nodes.push_back(new Node<2>(0, false, 0.0, 0.0));
        two_d_nodes.push_back(new Node<2>(1, false, 1.0, 0.0));
        two_d_nodes.push_back(new Node<2>(2, false, 0.0, 1.0));
        Element<2,2> two_d_element(0u, two_d_nodes);
        ChastePoint<2> zero2(0,0);

        std::vector<Node<3>*> three_d_nodes;
        three_d_nodes.push_back(new Node<3>(0, false, 0.0, 0.0, 0.0));
        three_d_nodes.push_back(new Node<3>(1, false, 1.0, 0.0, 0.0));
        three_d_nodes.push_back(new Node<3>(2, false, 0.0, 1.0, 0.0));
        three_d_nodes.push_back(new Node<3>(3, false, 0.0, 0.0, 1.0));
        Element<3,3> three_d_element(0u, three_d_nodes);
        ChastePoint<3> zero3(0,0,0);
        double u = 2.0;

        HeatEquationWithElementDependentSourceTerm<1> pde1;
        HeatEquationWithElementDependentSourceTerm<2> pde2;
        HeatEquationWithElementDependentSourceTerm<3> pde3;

        TS_ASSERT_DELTA(pde1.ComputeSourceTerm(zero1, u, &one_d_element), 0.0, 1e-12);
        one_d_element.ResetIndex(1u);
        TS_ASSERT_DELTA(pde1.ComputeSourceTerm(zero1, u, &one_d_element), 1.0, 1e-12);

        TS_ASSERT_DELTA(pde2.ComputeSourceTerm(zero2, u, &two_d_element), 0.0, 1e-12);
        two_d_element.ResetIndex(1u);
        TS_ASSERT_DELTA(pde2.ComputeSourceTerm(zero2, u, &two_d_element), 1.0, 1e-12);

        TS_ASSERT_DELTA(pde3.ComputeSourceTerm(zero3, u, &three_d_element), 0.0, 1e-12);
        three_d_element.ResetIndex(1u);
        TS_ASSERT_DELTA(pde3.ComputeSourceTerm(zero3, u, &three_d_element), 1.0, 1e-12);

        TS_ASSERT_DELTA(pde1.ComputeDuDtCoefficientFunction(zero1), 1.0, 1e-12);
        TS_ASSERT_DELTA(pde2.ComputeDuDtCoefficientFunction(zero2), 1.0, 1e-12);
        TS_ASSERT_DELTA(pde3.ComputeDuDtCoefficientFunction(zero3), 1.0, 1e-12);

        // Diffusion matrices should be equal to identity
        c_matrix<double, 1, 1> diff1 = pde1.ComputeDiffusionTerm(zero1);
        c_matrix<double, 2, 2> diff2 = pde2.ComputeDiffusionTerm(zero2);
        c_matrix<double, 3, 3> diff3 = pde3.ComputeDiffusionTerm(zero3);

        TS_ASSERT_DELTA(diff1(0,0), 1, 1e-12);

        TS_ASSERT_DELTA(diff2(0,0), 1, 1e-12);
        TS_ASSERT_DELTA(diff2(1,1), 1, 1e-12);
        TS_ASSERT_DELTA(diff2(0,1), 0, 1e-12);

        TS_ASSERT_DELTA(diff3(0,0), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(1,1), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(2,2), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(0,1), 0, 1e-12);
        TS_ASSERT_DELTA(diff3(0,2), 0, 1e-12);
        TS_ASSERT_DELTA(diff3(1,2), 0, 1e-12);

        delete one_d_nodes[0];
        delete one_d_nodes[1];

        delete two_d_nodes[0];
        delete two_d_nodes[1];
        delete two_d_nodes[2];

        delete three_d_nodes[0];
        delete three_d_nodes[1];
        delete three_d_nodes[2];
        delete three_d_nodes[3];
    }
// divide and conquer algorithm of the sequencing
  void CompNovoIdentificationCID::getDecompositionsDAC_(set<String> & sequences, Size left, Size right, DoubleReal peptide_weight, const PeakSpectrum & CID_spec, Map<DoubleReal, CompNovoIonScoringCID::IonScore> & ion_scores)
  {
    static DoubleReal oxonium_mass = EmpiricalFormula("H2O+").getMonoWeight();
    DoubleReal offset_suffix(CID_spec[left].getPosition()[0] - oxonium_mass);
    DoubleReal offset_prefix(peptide_weight - CID_spec[right].getPosition()[0]);

#ifdef DAC_DEBUG
    static Int depth_(0);
    ++depth_;
    String tabs_(depth_, '\t');
    cerr << tabs_ << "void getDecompositionsDAC(sequences[" << sequences.size() << "], " << left << ", " << right << ") ";
    cerr << CID_spec[left].getPosition()[0] << " " << CID_spec[right].getPosition()[0] << " diff=";
#endif

    DoubleReal diff = CID_spec[right].getPosition()[0] - CID_spec[left].getPosition()[0];

#ifdef DAC_DEBUG
    cerr << diff << endl;
    cerr << "offset_prefix=" << offset_prefix << ", offset_suffix=" << offset_suffix << endl;
#endif

    if (subspec_to_sequences_.has(left) && subspec_to_sequences_[left].has(right))
    {
      sequences = subspec_to_sequences_[left][right];

#ifdef DAC_DEBUG
      depth_--;
      cerr << tabs_ << "from cache DAC: " << CID_spec[left].getPosition()[0] << " " << CID_spec[right].getPosition()[0] << " " << sequences.size() << " " << left << " " << right << endl;
#endif
      return;
    }

    // no further solutions possible?
    if (diff < min_aa_weight_)
    {
#ifdef DAC_DEBUG
      depth_--;
#endif
      return;
    }

    // no further division needed?
    if (diff <= max_decomp_weight_)
    {
      vector<MassDecomposition> decomps;

      // if we are at the C-terminus use precursor_mass_tolerance_
      if (offset_prefix < precursor_mass_tolerance_)
      {
        Param decomp_param(mass_decomp_algorithm_.getParameters());
        decomp_param.setValue("tolerance", precursor_mass_tolerance_);
        mass_decomp_algorithm_.setParameters(decomp_param);
        getDecompositions_(decomps, diff);
        decomp_param.setValue("tolerance", fragment_mass_tolerance_);
        mass_decomp_algorithm_.setParameters(decomp_param);
      }
      else
      {
        getDecompositions_(decomps, diff);
      }
      //filterDecomps_(decomps);

#ifdef DAC_DEBUG
      cerr << tabs_ << "Found " << decomps.size() << " decomps" << endl;
      cerr << tabs_ << "Permuting...";
#endif

      //static Map<String, set<String> > permute_cache;
      for (vector<MassDecomposition>::const_iterator it = decomps.begin(); it != decomps.end(); ++it)
      {
#ifdef DAC_DEBUG
        cerr << it->toString() << endl;
#endif

        String exp_string = it->toExpandedString();
        if (!permute_cache_.has(exp_string))
        {
          permute_("", exp_string, sequences);
          permute_cache_[exp_string] = sequences;
        }
        else
        {
          sequences = permute_cache_[exp_string];
        }
      }

#ifdef DAC_DEBUG
      cerr << tabs_ << CID_spec[left].getPosition()[0] << " " << CID_spec[right].getPosition()[0] << " " << peptide_weight << endl;
      if (sequences.size() > max_subscore_number_)
      {
        cerr << tabs_ << "Reducing #sequences from " << sequences.size() << " to " << max_subscore_number_ << "(prefix=" << offset_prefix  << ", suffix=" << offset_suffix << ")...";
      }
#endif

      // C-terminus
      if (offset_suffix <= precursor_mass_tolerance_)
      {
        filterPermuts_(sequences);
      }

      // reduce the sequences
      reducePermuts_(sequences, CID_spec, offset_prefix, offset_suffix);
#ifdef DAC_DEBUG
      cerr << "Writing to cache " << left << " " << right << endl;
#endif
      subspec_to_sequences_[left][right] = sequences;

#ifdef DAC_DEBUG
      cerr << "ended" << endl;
      cerr << tabs_ << "DAC: " << CID_spec[left].getPosition()[0] << " " << CID_spec[right].getPosition()[0] << " " << sequences.size() << endl;
      depth_--;
#endif

      return;
    }

    // select suitable pivot peaks
    vector<Size> pivots;

    if (offset_suffix < precursor_mass_tolerance_ && offset_prefix < precursor_mass_tolerance_)
    {
      selectPivotIons_(pivots, left, right, ion_scores, CID_spec, peptide_weight, true);
    }
    else
    {
      selectPivotIons_(pivots, left, right, ion_scores, CID_spec, peptide_weight, false);
    }

    // run divide step
#ifdef DAC_DEBUG
    cerr << tabs_ << "Selected " << pivots.size() << " pivot ions: ";
    for (vector<Size>::const_iterator it = pivots.begin(); it != pivots.end(); ++it)
    {
      cerr << *it << "(" << CID_spec[*it].getPosition()[0] << ") ";
    }
    cerr << endl;
#endif

    for (vector<Size>::const_iterator it = pivots.begin(); it != pivots.end(); ++it)
    {
      set<String> seq1, seq2, new_sequences;

      // the smaller the 'gap' the greater the chance of not finding anything
      // so we we compute the smaller gap first
      DoubleReal diff1(CID_spec[*it].getPosition()[0] - CID_spec[left].getPosition()[0]);
      DoubleReal diff2(CID_spec[right].getPosition()[0] - CID_spec[*it].getPosition()[0]);

      if (diff1 < diff2)
      {
        getDecompositionsDAC_(seq1, left, *it, peptide_weight, CID_spec, ion_scores);
        if (seq1.empty())
        {
#ifdef DAC_DEBUG
          cerr << tabs_ << "first call produced 0 candidates (" << diff1 << ")" << endl;
#endif
          continue;
        }

        getDecompositionsDAC_(seq2, *it, right, peptide_weight, CID_spec, ion_scores);
      }
      else
      {
        getDecompositionsDAC_(seq2, *it, right, peptide_weight, CID_spec, ion_scores);
        if (seq2.empty())
        {
#ifdef DAC_DEBUG
          cerr << tabs_ << "second call produced 0 candidates (" << diff2 << ")" << endl;
#endif
          continue;
        }

        getDecompositionsDAC_(seq1, left, *it, peptide_weight, CID_spec, ion_scores);
      }

#ifdef DAC_DEBUG
      cerr << tabs_ << "Found " << seq1.size() << " solutions (1) " << diff1 << endl;
      cerr << tabs_ << "Found " << seq2.size() << " solutions (2) " << diff2 << endl;
      cerr << tabs_ << "inserting " << seq1.size() * seq2.size()  << " sequences" << endl;
#endif

      // C-terminus
      if (offset_suffix <= fragment_mass_tolerance_)
      {
        filterPermuts_(seq1);
      }

      // test if we found enough sequence candidates
      if (seq1.empty() || seq2.empty())
      {
        continue;
      }

      for (set<String>::const_iterator it1 = seq1.begin(); it1 != seq1.end(); ++it1)
      {
        for (set<String>::const_iterator it2 = seq2.begin(); it2 != seq2.end(); ++it2)
        {
          new_sequences.insert(*it2 + *it1);
        }
      }

      if (seq1.size() * seq2.size() > max_subscore_number_ /* && (offset_prefix > fragment_mass_tolerance_ || offset_suffix > fragment_mass_tolerance_)*/)
      {
#ifdef DAC_DEBUG
        cerr << tabs_ << CID_spec[left].getPosition()[0] << " " << CID_spec[right].getPosition()[0] << " " << peptide_weight << endl;
        cerr << tabs_ << "Reducing #sequences from " << new_sequences.size() << " to " << max_subscore_number_ << "(prefix=" << offset_prefix  << ", suffix=" << offset_suffix << ")...";
#endif
        if (offset_prefix > precursor_mass_tolerance_ || offset_suffix > precursor_mass_tolerance_)
        {
          reducePermuts_(new_sequences, CID_spec, offset_prefix, offset_suffix);
        }

#ifdef DAC_DEBUG
        for (set<String>::const_iterator it1 = new_sequences.begin(); it1 != new_sequences.end(); ++it1)
        {
          cerr << tabs_ << *it1 << endl;
        }
        cerr << endl;
#endif
      }

      for (set<String>::const_iterator sit = new_sequences.begin(); sit != new_sequences.end(); ++sit)
      {
        sequences.insert(*sit);
      }
    }
#ifdef DAC_DEBUG
    cerr << tabs_ << "Found sequences for " << CID_spec[left].getPosition()[0] << " " << CID_spec[right].getPosition()[0] << endl;
    for (set<String>::const_iterator sit = sequences.begin(); sit != sequences.end(); ++sit)
    {
      cerr << tabs_ << *sit << endl;
    }
#endif

    // reduce the permuts once again to reduce complexity
    if (offset_prefix > precursor_mass_tolerance_ || offset_suffix > precursor_mass_tolerance_)
    {
      reducePermuts_(sequences, CID_spec, offset_prefix, offset_suffix);
    }

#ifdef DAC_DEBUG
    cerr << "Writing to cache " << left << " " << right << endl;
#endif

    subspec_to_sequences_[left][right] = sequences;

#ifdef DAC_DEBUG
    depth_--;
    cerr << tabs_ << "DAC: " << CID_spec[left].getPosition()[0] << " " << CID_spec[right].getPosition()[0] << " " << sequences.size() << endl;
#endif
    return;

  }
Beispiel #13
0
  ExecStatus
  ElementUnionConst<SView,RView>::propagate(Space& home, const ModEventDelta&) {
    Region r(home);

    bool* stillSelected = r.alloc<bool>(n_iv);

    bool loopVar;
    do {
      loopVar = false;
      for (int i=n_iv; i--;)
        stillSelected[i] = false;

      // Cache the upper bound iterator, as we have to
      // modify the upper bound while iterating
      LubRanges<RView> x1ub(x1);
      Iter::Ranges::Cache x1ubc(r,x1ub);
      Iter::Ranges::ToValues<Iter::Ranges::Cache>
        vx1ub(x1ubc);

      GlbRanges<RView> x1lb(x1);
      Iter::Ranges::Cache x1lbc(r,x1lb);
      Iter::Ranges::ToValues<Iter::Ranges::Cache>
        vx1(x1lbc);

      // In the first iteration, compute in before[i] the union
      // of all the upper bounds of the x_i. At the same time,
      // exclude inconsistent x_i from x1.

      GLBndSet sofarBefore(home);
      LUBndSet selectedInter(home, IntSet (Limits::min,
                                   Limits::max));
      GLBndSet* before =
        static_cast<GLBndSet*>(r.ralloc(sizeof(GLBndSet)*n_iv));

      unsigned int maxCard = 0;
      unsigned int minCard = Limits::card;

      while (vx1ub()) {
        int i = vx1ub.val();

        IntSetRanges candCardR(iv[i]);
        unsigned int candidateCard = Iter::Ranges::size(candCardR);

        IntSetRanges candlb(iv[i]);
        LubRanges<SView> x0ub(x0);
        Iter::Ranges::Diff<IntSetRanges,
          LubRanges<SView> > diff(candlb, x0ub);

        bool selectSingleInconsistent = false;
        if (x1.cardMax() <= 1) {
          GlbRanges<SView> x0lb(x0);
          IntSetRanges candub(iv[i]);
          Iter::Ranges::Diff<GlbRanges<SView>,
                             IntSetRanges > diff2(x0lb, candub);
          selectSingleInconsistent = diff2() || candidateCard < x0.cardMin();
        }

        // exclude inconsistent x_i
        // an x_i is inconsistent if
        //  * at most one x_i can be selected and there are
        //    elements in x_0 that can't be in x_i
        //    (selectSingleInconsistent)
        //  * its min cardinality is greater than maxCard of x0
        //  * inter is not empty (there are elements in x_i
        //    that can't be in x_0)
        if (selectSingleInconsistent ||
            candidateCard > x0.cardMax() ||
            diff()) {
          ModEvent me = (x1.exclude(home,i));
          loopVar |= me_modified(me);
          GECODE_ME_CHECK(me);
        } else {
          stillSelected[i] = true;
          // if x_i is consistent, check whether we know
          // that its index is in x1
          if (vx1() && vx1.val()==i) {
            // x0 >= candidate, candidate <= x0
            // GlbRanges<SView> candlb(candidate);
            IntSetRanges candlb(iv[i]);
            ModEvent me = x0.includeI(home,candlb);
            loopVar |= me_modified(me);
            GECODE_ME_CHECK(me);
            ++vx1;
          }
          new (&before[i]) GLBndSet(home);
          before[i].update(home,sofarBefore);
          IntSetRanges cub(iv[i]);
          sofarBefore.includeI(home,cub);
          IntSetRanges clb(iv[i]);
          selectedInter.intersectI(home,clb);
          maxCard = std::max(maxCard, candidateCard);
          minCard = std::min(minCard, candidateCard);
        }

        ++vx1ub;
      }

      if (x1.cardMax()==0) {
        // Selector is empty, hence the result must be empty
        {
          GECODE_ME_CHECK(x0.cardMax(home,0));
        }
        for (int i=n_iv; i--;)
          if (stillSelected[i])
            before[i].dispose(home);
        selectedInter.dispose(home);
        sofarBefore.dispose(home);
        return home.ES_SUBSUMED(*this);
      }

      if (x1.cardMin() > 0) {
        // Selector is not empty, hence the intersection of the
        // possibly selected lower bounds is contained in x0
        BndSetRanges si(selectedInter);
        ModEvent me = x0.includeI(home, si);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
        me = x0.cardMin(home, minCard);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
      }
      selectedInter.dispose(home);

      if (x1.cardMax() <= 1) {
        ModEvent me = x0.cardMax(home, maxCard);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
      }

      {
        // x0 <= sofarBefore
        BndSetRanges sfB(sofarBefore);
        ModEvent me = x0.intersectI(home,sfB);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
      }

      sofarBefore.dispose(home);

      GLBndSet sofarAfter(home);

      // In the second iteration, this time backwards, compute
      // sofarAfter as the union of all lub(x_j) with j>i
      for (int i=n_iv; i--;) {
        if (!stillSelected[i])
          continue;
        BndSetRanges b(before[i]);
        BndSetRanges s(sofarAfter);
        GlbRanges<SView> x0lb(x0);
        Iter::Ranges::Union<BndSetRanges, BndSetRanges> inter(b,s);
        Iter::Ranges::Diff<GlbRanges<SView>,
          Iter::Ranges::Union<BndSetRanges,BndSetRanges> > diff(x0lb, inter);
        if (diff()) {
          ModEvent me = (x1.include(home,i));
          loopVar |= me_modified(me);
          GECODE_ME_CHECK(me);

          // candidate != extra
          IntSetRanges ivi(iv[i]);
          if (!Iter::Ranges::subset(diff, ivi))
            GECODE_ME_CHECK(ME_SET_FAILED);
        }

        IntSetRanges iviub(iv[i]);
        sofarAfter.includeI(home,iviub);
        before[i].dispose(home);
      }
      sofarAfter.dispose(home);

    } while (loopVar);

    if (x1.assigned()) {
      assert(x0.assigned());
      return home.ES_SUBSUMED(*this);
    }

    return ES_FIX;
  }
void CudaConjugateGradientSolver::solve(void * X,
                                        CudaCSRMatrix * A,
                                        void * fixed,
                                        float * error)
{
    // cglg.writeVec3(m_rhs, m_dimension, "cg b", CudaDbgLog::FAlways);
    //cglg.writeMat33(A->valueBuf(),
    //				A->numNonZero(),
    //				" cg A ", CudaDbgLog::FAlways);

    cuConjugateGradient_prevresidual((float3 *)previous(),
                                     (float3 *)residual(),
                                     (mat33 *)A->deviceValue(),
                                     (uint *)A->deviceRowPtr(),
                                     (uint *)A->deviceColInd(),
                                     (uint *)fixed,
                                     (float3 *)X,
                                     (float3 *)rightHandSide(),
                                     m_dimension);

    for(int i=0; i<FemGlobal::CGSolverMaxNumIterations; i++) {
        cuConjugateGradient_Ax((float3 *)previous(),
                               (float3 *)updated(),
                               (float3 *)residual(),
                               (float *)diff(),
                               (float *)diff2(),
                               (mat33 *)A->deviceValue(),
                               (uint *)A->deviceRowPtr(),
                               (uint *)A->deviceColInd(),
                               (uint *)fixed,
                               m_dimension);

        float d =0;
        float d2=0;

        m_reduce->sum<float>(d, (float *)diff(), m_dimension);
        m_reduce->sum<float>(d2, (float *)diff2(), m_dimension);

        if(fabs(d2)< 1e-10f)
            d2 = 1e-10f;

        float d3 = d/d2;
        cuConjugateGradient_addX((float3 *)X,
                                 (float3 *)residual(),
                                 (float *)diff(),
                                 (float3 *)previous(),
                                 (float3 *)updated(),
                                 d3,
                                 (uint *)fixed,
                                 m_dimension);

        float d1 = 0.f;

        m_reduce->sum<float>(d1, (float *)diff(), m_dimension);

        if(error) *error = d1;

        if(d1 < 0.01f)
            break;

        if(fabs(d)<1e-10f)
            d = 1e-10f;

        float d4 = d1/d;
        cuConjugateGradient_addResidual((float3 *)previous(),
                                        (float3 *)residual(),
                                        d4,
                                        (uint *)fixed,
                                        m_dimension);
    }
}
void QgsGeometryOverlapCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
{
  QString errMsg;
  QgsGeometryOverlapCheckError *overlapError = static_cast<QgsGeometryOverlapCheckError *>( error );

  QgsFeaturePool *featurePoolA = mContext->featurePools[ overlapError->layerId() ];
  QgsFeaturePool *featurePoolB = mContext->featurePools[ overlapError->overlappedFeature().first ];
  QgsFeature featureA;
  QgsFeature featureB;
  if ( !featurePoolA->get( overlapError->featureId(), featureA ) ||
       !featurePoolB->get( overlapError->overlappedFeature().second, featureB ) )
  {
    error->setObsolete();
    return;
  }

  // Check if error still applies
  QgsGeometryCheckerUtils::LayerFeature layerFeatureA( featurePoolA, featureA, true );
  QgsGeometryCheckerUtils::LayerFeature layerFeatureB( featurePoolB, featureB, true );
  std::unique_ptr< QgsGeometryEngine > geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureA.geometry(), mContext->reducedTolerance );

  if ( !geomEngineA->overlaps( layerFeatureB.geometry() ) )
  {
    error->setObsolete();
    return;
  }
  std::unique_ptr< QgsAbstractGeometry > interGeom( geomEngineA->intersection( layerFeatureB.geometry(), &errMsg ) );
  if ( !interGeom )
  {
    error->setFixFailed( tr( "Failed to compute intersection between overlapping features: %1" ).arg( errMsg ) );
    return;
  }

  // Search which overlap part this error parametrizes (using fuzzy-matching of the area and centroid...)
  QgsAbstractGeometry *interPart = nullptr;
  for ( int iPart = 0, nParts = interGeom->partCount(); iPart < nParts; ++iPart )
  {
    QgsAbstractGeometry *part = QgsGeometryCheckerUtils::getGeomPart( interGeom.get(), iPart );
    if ( std::fabs( part->area() - overlapError->value().toDouble() ) < mContext->reducedTolerance &&
         QgsGeometryCheckerUtils::pointsFuzzyEqual( part->centroid(), overlapError->location(), mContext->reducedTolerance ) )
    {
      interPart = part;
      break;
    }
  }
  if ( !interPart || interPart->isEmpty() )
  {
    error->setObsolete();
    return;
  }

  // Fix error
  if ( method == NoChange )
  {
    error->setFixed( method );
  }
  else if ( method == Subtract )
  {
    std::unique_ptr< QgsAbstractGeometry > diff1( geomEngineA->difference( interPart, &errMsg ) );
    if ( !diff1 || diff1->isEmpty() )
    {
      diff1.reset();
    }
    else
    {
      QgsGeometryCheckerUtils::filter1DTypes( diff1.get() );
    }
    std::unique_ptr< QgsGeometryEngine > geomEngineB = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureB.geometry(), mContext->reducedTolerance );
    std::unique_ptr< QgsAbstractGeometry > diff2( geomEngineB->difference( interPart, &errMsg ) );
    if ( !diff2 || diff2->isEmpty() )
    {
      diff2.reset();
    }
    else
    {
      QgsGeometryCheckerUtils::filter1DTypes( diff2.get() );
    }
    double shared1 = diff1 ? QgsGeometryCheckerUtils::sharedEdgeLength( diff1.get(), interPart, mContext->reducedTolerance ) : 0;
    double shared2 = diff2 ? QgsGeometryCheckerUtils::sharedEdgeLength( diff2.get(), interPart, mContext->reducedTolerance ) : 0;
    if ( !diff1 || !diff2 || shared1 == 0. || shared2 == 0. )
    {
      error->setFixFailed( tr( "Could not find shared edges between intersection and overlapping features" ) );
    }
    else
    {
      if ( shared1 < shared2 )
      {
        diff1->transform( featurePoolA->getLayerToMapTransform(), QgsCoordinateTransform::ReverseTransform );
        featureA.setGeometry( QgsGeometry( std::move( diff1 ) ) );

        changes[error->layerId()][featureA.id()].append( Change( ChangeFeature, ChangeChanged ) );
        featurePoolA->updateFeature( featureA );
      }
      else
      {
        diff2->transform( featurePoolB->getLayerToMapTransform(), QgsCoordinateTransform::ReverseTransform );
        featureB.setGeometry( QgsGeometry( std::move( diff2 ) ) );

        changes[overlapError->overlappedFeature().first][featureB.id()].append( Change( ChangeFeature, ChangeChanged ) );
        featurePoolB->updateFeature( featureB );
      }

      error->setFixed( method );
    }
  }
  else
  {
    error->setFixFailed( tr( "Unknown method" ) );
  }
}
Beispiel #16
0
  ExecStatus
  SuperOfInter<View0,View1,View2>::propagate(Space& home, const ModEventDelta& med) {

    bool allassigned = x0.assigned() && x1.assigned() && x2.assigned();

    ModEvent me0 = View0::me(med);
    ModEvent me1 = View1::me(med);
    ModEvent me2 = View2::me(med);

    bool modified = false;

    do {
      // glb(x2) >= glb(x0) ^ glb(x1)
      if ( modified || Rel::testSetEventLB(me0,me1)) {
        GlbRanges<View0> lb0(x0);
        GlbRanges<View1> lb1(x1);
        Iter::Ranges::Inter<GlbRanges<View0>,GlbRanges<View1> >
          is(lb0, lb1);

        GECODE_ME_CHECK_MODIFIED(modified,x2.includeI(home,is));
      }

      // lub(x0) -= glb(x1)-lub(x2)
      // lub(x1) -= glb(x0)-lub(x2)
      if ( modified || Rel::testSetEventAnyB(me0,me1,me2)) {
         modified = false;
        GlbRanges<View1> lb12(x1);
        LubRanges<View2> ub22(x2);
        Iter::Ranges::Diff<GlbRanges<View1>, LubRanges<View2> >
          diff1(lb12, ub22);

        GECODE_ME_CHECK_MODIFIED(modified, x0.excludeI(home,diff1));

        GlbRanges<View0> lb01(x0);
        LubRanges<View2> ub23(x2);
        Iter::Ranges::Diff<GlbRanges<View0>, LubRanges<View2> >
          diff2(lb01, ub23);

        GECODE_ME_CHECK_MODIFIED(modified, x1.excludeI(home,diff2));
      } else {
         modified = false;
      }

      // Cardinality propagation
      if ( modified ||
            Rel::testSetEventCard(me0,me1,me2) ||
           Rel::testSetEventUB(me0,me1)
           ) {

        LubRanges<View0> ub0(x0);
        LubRanges<View1> ub1(x1);
        Iter::Ranges::Union<LubRanges<View0>, LubRanges<View1> > u(ub0,ub1);

        unsigned int m = Iter::Ranges::size(u);

        if (m < x0.cardMin() + x1.cardMin()) {
          GECODE_ME_CHECK_MODIFIED(modified,
                            x2.cardMin( home,
                                        x0.cardMin()+x1.cardMin() - m ) );
        }
        if (m + x2.cardMax() > x1.cardMin()) {
          GECODE_ME_CHECK_MODIFIED(modified,
                            x0.cardMax( home,
                                        m+x2.cardMax()-x1.cardMin() )  );
        }
        if (m + x2.cardMax() > x0.cardMin()) {
          GECODE_ME_CHECK_MODIFIED(modified,
                            x1.cardMax( home,
                                        m+x2.cardMax()-x0.cardMin() )  );
        }
      }
    } while (modified);


    if (shared(x0,x1,x2)) {
      if (allassigned) {
        return home.ES_SUBSUMED(*this);
      } else {
        return ES_NOFIX;
      }
    } else {
      if (x0.assigned() + x1.assigned() + x2.assigned() >= 2) {
         return home.ES_SUBSUMED(*this);
      } else {
        return ES_FIX;
      }
    }

  }
void
CartesianCellDoubleConservativeLinearRefine::refine(
   hier::Patch& fine,
   const hier::Patch& coarse,
   const int dst_component,
   const int src_component,
   const hier::Box& fine_box,
   const hier::IntVector& ratio) const
{
   const tbox::Dimension& dim(fine.getDim());
   TBOX_ASSERT_DIM_OBJDIM_EQUALITY3(dim, coarse, fine_box, ratio);

   std::shared_ptr<pdat::CellData<double> > cdata(
      SAMRAI_SHARED_PTR_CAST<pdat::CellData<double>, hier::PatchData>(
         coarse.getPatchData(src_component)));
   std::shared_ptr<pdat::CellData<double> > fdata(
      SAMRAI_SHARED_PTR_CAST<pdat::CellData<double>, hier::PatchData>(
         fine.getPatchData(dst_component)));
   TBOX_ASSERT(cdata);
   TBOX_ASSERT(fdata);
   TBOX_ASSERT(cdata->getDepth() == fdata->getDepth());

   const hier::Box cgbox(cdata->getGhostBox());

   const hier::Index& cilo = cgbox.lower();
   const hier::Index& cihi = cgbox.upper();
   const hier::Index& filo = fdata->getGhostBox().lower();
   const hier::Index& fihi = fdata->getGhostBox().upper();

   const std::shared_ptr<CartesianPatchGeometry> cgeom(
      SAMRAI_SHARED_PTR_CAST<CartesianPatchGeometry, hier::PatchGeometry>(
         coarse.getPatchGeometry()));
   const std::shared_ptr<CartesianPatchGeometry> fgeom(
      SAMRAI_SHARED_PTR_CAST<CartesianPatchGeometry, hier::PatchGeometry>(
         fine.getPatchGeometry()));

   TBOX_ASSERT(cgeom);
   TBOX_ASSERT(fgeom);

   const hier::Box coarse_box = hier::Box::coarsen(fine_box, ratio);
   const hier::Index& ifirstc = coarse_box.lower();
   const hier::Index& ilastc = coarse_box.upper();
   const hier::Index& ifirstf = fine_box.lower();
   const hier::Index& ilastf = fine_box.upper();

   const hier::IntVector tmp_ghosts(dim, 0);
   std::vector<double> diff0(cgbox.numberCells(0) + 1);
   pdat::CellData<double> slope0(cgbox, 1, tmp_ghosts);

   for (int d = 0; d < fdata->getDepth(); ++d) {
      if ((dim == tbox::Dimension(1))) {
         SAMRAI_F77_FUNC(cartclinrefcelldoub1d, CARTCLINREFCELLDOUB1D) (ifirstc(0),
            ilastc(0),
            ifirstf(0), ilastf(0),
            cilo(0), cihi(0),
            filo(0), fihi(0),
            &ratio[0],
            cgeom->getDx(),
            fgeom->getDx(),
            cdata->getPointer(d),
            fdata->getPointer(d),
            &diff0[0], slope0.getPointer());
      } else if ((dim == tbox::Dimension(2))) {

         std::vector<double> diff1(cgbox.numberCells(1) + 1);
         pdat::CellData<double> slope1(cgbox, 1, tmp_ghosts);

         SAMRAI_F77_FUNC(cartclinrefcelldoub2d, CARTCLINREFCELLDOUB2D) (ifirstc(0),
            ifirstc(1), ilastc(0), ilastc(1),
            ifirstf(0), ifirstf(1), ilastf(0), ilastf(1),
            cilo(0), cilo(1), cihi(0), cihi(1),
            filo(0), filo(1), fihi(0), fihi(1),
            &ratio[0],
            cgeom->getDx(),
            fgeom->getDx(),
            cdata->getPointer(d),
            fdata->getPointer(d),
            &diff0[0], slope0.getPointer(),
            &diff1[0], slope1.getPointer());
      } else if ((dim == tbox::Dimension(3))) {

         std::vector<double> diff1(cgbox.numberCells(1) + 1);
         pdat::CellData<double> slope1(cgbox, 1, tmp_ghosts);

         std::vector<double> diff2(cgbox.numberCells(2) + 1);
         pdat::CellData<double> slope2(cgbox, 1, tmp_ghosts);

         SAMRAI_F77_FUNC(cartclinrefcelldoub3d, CARTCLINREFCELLDOUB3D) (ifirstc(0),
            ifirstc(1), ifirstc(2),
            ilastc(0), ilastc(1), ilastc(2),
            ifirstf(0), ifirstf(1), ifirstf(2),
            ilastf(0), ilastf(1), ilastf(2),
            cilo(0), cilo(1), cilo(2),
            cihi(0), cihi(1), cihi(2),
            filo(0), filo(1), filo(2),
            fihi(0), fihi(1), fihi(2),
            &ratio[0],
            cgeom->getDx(),
            fgeom->getDx(),
            cdata->getPointer(d),
            fdata->getPointer(d),
            &diff0[0], slope0.getPointer(),
            &diff1[0], slope1.getPointer(),
            &diff2[0], slope2.getPointer());
      } else {
         TBOX_ERROR("CartesianCellDoubleConservativeLinearRefine error...\n"
            << "dim > 3 not supported." << std::endl);

      }
   }
}