From: geay Date: Wed, 12 Mar 2014 09:07:00 +0000 (+0100) Subject: cherry-pick between a669 and 19a96 of V7_main X-Git-Tag: V7_3_1rc2^2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2Fagy%2FV731rc2;p=tools%2Fmedcoupling.git cherry-pick between a669 and 19a96 of V7_main --- diff --git a/src/INTERP_KERNEL/ConvexIntersector.hxx b/src/INTERP_KERNEL/ConvexIntersector.hxx index dd842b553..f627afd26 100644 --- a/src/INTERP_KERNEL/ConvexIntersector.hxx +++ b/src/INTERP_KERNEL/ConvexIntersector.hxx @@ -40,7 +40,7 @@ namespace INTERP_KERNEL static const NumberingPolicy numPol=MyMeshType::My_numPol; public: ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double medianPlane, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); diff --git a/src/INTERP_KERNEL/ConvexIntersector.txx b/src/INTERP_KERNEL/ConvexIntersector.txx index f9ee8d44d..3986a4a24 100644 --- a/src/INTERP_KERNEL/ConvexIntersector.txx +++ b/src/INTERP_KERNEL/ConvexIntersector.txx @@ -39,9 +39,9 @@ namespace INTERP_KERNEL { CONVINTERSECTOR_TEMPLATE CONVEX_INTERSECTOR_::ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate , int oriantation, int printLevel) - :InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, medianPlane, doRotate, oriantation, printLevel), + :InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, doRotate, oriantation, printLevel), _epsilon(precision*dimCaracteristic) { if(PlanarIntersector::_print_level >= 1) diff --git a/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx b/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx index 121a2c255..282a79174 100644 --- a/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx +++ b/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx @@ -234,6 +234,14 @@ void GaussInfo::initLocalInfo() const CellModel& cellModel(CellModel::GetCellModel(_my_geometry)); switch( _my_geometry ) { + case NORM_POINT1: + _my_local_ref_dim = 0; + _my_local_nb_ref = 1; + point1Init(); + aSatify = isSatisfy(); + CHECK_MACRO; + break; + case NORM_SEG2: _my_local_ref_dim = 1; _my_local_nb_ref = 2; @@ -277,6 +285,14 @@ void GaussInfo::initLocalInfo() } break; + case NORM_TRI7: + _my_local_ref_dim = 2; + _my_local_nb_ref = 7; + tria7aInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + break; + case NORM_QUAD4: { _my_local_ref_dim = 2; @@ -401,18 +417,19 @@ void GaussInfo::initLocalInfo() break; case NORM_PENTA15: - _my_local_ref_dim = 3; - _my_local_nb_ref = 15; - penta15aInit(); - aSatify = isSatisfy(); - - if(!aSatify) - { - penta15bInit(); - aSatify = isSatisfy(); - CHECK_MACRO; - } - break; + { + _my_local_ref_dim = 3; + _my_local_nb_ref = 15; + MapToShapeFunction PENTA15PTR[]={Penta15aInit,Penta15bInit}; + std::size_t NB_OF_PENTA15PTR(sizeof(PENTA15PTR)/sizeof(MapToShapeFunction)); + for(std::size_t i=0;i& p1, const std::pair& subNodes) +{ + Bounds b; + b.prepareForAggregation(); + b.aggregate(getBounds()); + double xBary,yBary; + double dimChar(b.getCaracteristicDim()); + b.getBarycenter(xBary,yBary); + applySimilarity(xBary,yBary,dimChar); + _start->applySimilarity(xBary,yBary,dimChar); + _end->applySimilarity(xBary,yBary,dimChar); + // + std::size_t sz(subNodes.size()),i(0); + std::vector< std::pair > an2(sz); + std::map m; + for(std::vector::const_iterator it=subNodes.begin();it!=subNodes.end();it++,i++) + { + Node *n(new Node(coo[2*(*it)],coo[2*(*it)+1])); + n->applySimilarity(xBary,yBary,dimChar); + m[n]=*it; + an2[i]=std::pair(getCharactValueBtw0And1(*n),n); + } + std::sort(an2.begin(),an2.end()); + // + bool ret(false); + for(i=0;i::const_iterator it2=m.begin();it2!=m.end();it2++) + (*it2).first->decrRef(); + return ret; +} + /** * Sort nodes so that they all lie consecutively on the edge that has been cut. */ diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx index aa0164d7f..69e0025f0 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx @@ -238,6 +238,7 @@ namespace INTERP_KERNEL virtual double getCurveLength() const = 0; virtual void getBarycenter(double *bary) const = 0; virtual void getBarycenterOfZone(double *bary) const = 0; + virtual void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const = 0; //! Retrieves a point that is owning to this, well placed for IN/OUT detection of this. Typically midlle of this is returned. virtual Node *buildRepresentantOfMySelf() const = 0; //! Given a magnitude specified by sub-type returns if in or not. See getCharactValue method. @@ -264,6 +265,7 @@ namespace INTERP_KERNEL virtual void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const = 0; bool isEqual(const Edge& other) const; public: + bool sortSubNodesAbs(const double *coo, std::vector& subNodes); void sortIdsAbs(const std::vector& addNodes, const std::map& mapp1, const std::map& mapp2, std::vector& edgesThis); virtual void fillGlobalInfoAbs(bool direction, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const = 0; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx index 46b2fb156..5a867037d 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx @@ -630,6 +630,21 @@ void EdgeArcCircle::getBarycenterOfZone(double *bary) const +tmp2*(tmp4-tmp3+(tmp3*tmp3*tmp3-tmp4*tmp4*tmp4)/3.)/2.; } +void EdgeArcCircle::getMiddleOfPoints(const double *p1, const double *p2, double *mid) const +{ + double dx1((p1[0]-_center[0])/_radius),dy1((p1[1]-_center[1])/_radius),dx2((p2[0]-_center[0])/_radius),dy2((p2[1]-_center[1])/_radius); + double angle1(GetAbsoluteAngleOfNormalizedVect(dx1,dy1)),angle2(GetAbsoluteAngleOfNormalizedVect(dx2,dy2)); + // + double myDelta1(angle1-_angle0),myDelta2(angle2-_angle0); + if(_angle>0.) + { myDelta1=myDelta1>=0.?myDelta1:myDelta1+2.*M_PI; myDelta2=myDelta2>=0.?myDelta2:myDelta2+2.*M_PI; } + else + { myDelta1=myDelta1<=0.?myDelta1:myDelta1-2.*M_PI; myDelta2=myDelta2<=0.?myDelta2:myDelta2-2.*M_PI; } + //// + mid[0]=_center[0]+_radius*cos(_angle0+(myDelta1+myDelta2)/2.); + mid[1]=_center[1]+_radius*sin(_angle0+(myDelta1+myDelta2)/2.); +} + /*! * Characteristic value used is angle in ]_Pi;Pi[ from axe 0x. */ diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx index 321cb0ed5..4bfaecb97 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx @@ -79,6 +79,7 @@ namespace INTERP_KERNEL double getCurveLength() const; void getBarycenter(double *bary) const; void getBarycenterOfZone(double *bary) const; + void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const; bool isIn(double characterVal) const; Node *buildRepresentantOfMySelf() const; bool isLower(double val1, double val2) const; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx index 6b7e5859c..d08ab4330 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx @@ -273,6 +273,15 @@ void EdgeLin::getBarycenterOfZone(double *bary) const bary[1]=(x1-x2)*(y1*(y1+y2)+y2*y2)/6.; } +/*! + * Here \a this is not used (contrary to EdgeArcCircle class). + */ +void EdgeLin::getMiddleOfPoints(const double *p1, const double *p2, double *mid) const +{ + mid[0]=(p1[0]+p2[0])/2.; + mid[1]=(p1[1]+p2[1])/2.; +} + double EdgeLin::getCurveLength() const { double x=(*_start)[0]-(*_end)[0]; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx index 0a5258ed2..926ec893d 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx @@ -61,6 +61,7 @@ namespace INTERP_KERNEL double getCurveLength() const; void getBarycenter(double *bary) const; void getBarycenterOfZone(double *bary) const; + void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const; bool isIn(double characterVal) const; Node *buildRepresentantOfMySelf() const; double getCharactValue(const Node& node) const; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx index e4ecd62bc..9bbe6ce55 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx @@ -72,7 +72,7 @@ QuadraticPolygon::~QuadraticPolygon() QuadraticPolygon *QuadraticPolygon::BuildLinearPolygon(std::vector& nodes) { - QuadraticPolygon *ret=new QuadraticPolygon; + QuadraticPolygon *ret(new QuadraticPolygon); std::size_t size=nodes.size(); for(std::size_t i=0;i& node QuadraticPolygon *QuadraticPolygon::BuildArcCirclePolygon(std::vector& nodes) { - QuadraticPolygon *ret=new QuadraticPolygon; + QuadraticPolygon *ret(new QuadraticPolygon); std::size_t size=nodes.size(); for(std::size_t i=0;i& n return ret; } +Edge *QuadraticPolygon::BuildLinearEdge(std::vector& nodes) +{ + if(nodes.size()!=2) + throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildLinearEdge : input vector is expected to be of size 2 !"); + Edge *ret(new EdgeLin(nodes[0],nodes[1])); + nodes[0]->decrRef(); nodes[1]->decrRef(); + return ret; +} + +Edge *QuadraticPolygon::BuildArcCircleEdge(std::vector& nodes) +{ + if(nodes.size()!=3) + throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildArcCircleEdge : input vector is expected to be of size 3 !"); + EdgeLin *e1(new EdgeLin(nodes[0],nodes[2])),*e2(new EdgeLin(nodes[2],nodes[1])); + SegSegIntersector inters(*e1,*e2); + bool colinearity=inters.areColinears(); + delete e1; delete e2; + Edge *ret(0); + if(colinearity) + ret=new EdgeLin(nodes[0],nodes[1]); + else + ret=new EdgeArcCircle(nodes[0],nodes[2],nodes[1]); + nodes[0]->decrRef(); nodes[1]->decrRef(); nodes[2]->decrRef(); + return ret; +} + void QuadraticPolygon::BuildDbgFile(const std::vector& nodes, const char *fileName) { std::ofstream file(fileName); diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx index 4df9e861b..c6d235e1c 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx @@ -48,6 +48,8 @@ namespace INTERP_KERNEL INTERPKERNEL_EXPORT QuadraticPolygon(const char *fileName); INTERPKERNEL_EXPORT static QuadraticPolygon *BuildLinearPolygon(std::vector& nodes); INTERPKERNEL_EXPORT static QuadraticPolygon *BuildArcCirclePolygon(std::vector& nodes); + INTERPKERNEL_EXPORT static Edge *BuildLinearEdge(std::vector& nodes); + INTERPKERNEL_EXPORT static Edge *BuildArcCircleEdge(std::vector& nodes); INTERPKERNEL_EXPORT static void BuildDbgFile(const std::vector& nodes, const char *fileName); INTERPKERNEL_EXPORT ~QuadraticPolygon(); INTERPKERNEL_EXPORT void closeMe() const; diff --git a/src/INTERP_KERNEL/Geometric2DIntersector.hxx b/src/INTERP_KERNEL/Geometric2DIntersector.hxx index 7c077aeae..ca01ce89a 100644 --- a/src/INTERP_KERNEL/Geometric2DIntersector.hxx +++ b/src/INTERP_KERNEL/Geometric2DIntersector.hxx @@ -42,7 +42,7 @@ namespace INTERP_KERNEL static const NumberingPolicy numPol=MyMeshType::My_numPol; public: Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double medianPlane, double precision, int orientation); + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); double intersectGeometry1D(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, bool& isColinear); diff --git a/src/INTERP_KERNEL/Geometric2DIntersector.txx b/src/INTERP_KERNEL/Geometric2DIntersector.txx index b6bed16a9..1952deb28 100644 --- a/src/INTERP_KERNEL/Geometric2DIntersector.txx +++ b/src/INTERP_KERNEL/Geometric2DIntersector.txx @@ -42,9 +42,9 @@ namespace INTERP_KERNEL { INTERSECTOR_TEMPLATE GEO2D_INTERSECTOR::Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double medianPlane, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation): - InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, medianPlane, true, orientation, 0) + InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, true, orientation, 0) { QUADRATIC_PLANAR::_precision=precision; } @@ -63,7 +63,7 @@ namespace INTERP_KERNEL QuadraticPolygon *p2=buildPolygonFrom(CoordsS,tS); double ret=p1->intersectWithAbs(*p2); delete p1; delete p2; - return ret; + return orientation*ret; } INTERSECTOR_TEMPLATE @@ -81,7 +81,7 @@ namespace INTERP_KERNEL QuadraticPolygon *p2=buildPolygonOfOneEdgeFrom(CoordsS,tS); double ret=p1->intersectWithAbs1D(*p2, isColinear); delete p1; delete p2; - return ret; + return orientation*ret; } INTERSECTOR_TEMPLATE diff --git a/src/INTERP_KERNEL/Interpolation2D1D.txx b/src/INTERP_KERNEL/Interpolation2D1D.txx index 7f4283eac..8eed00910 100644 --- a/src/INTERP_KERNEL/Interpolation2D1D.txx +++ b/src/INTERP_KERNEL/Interpolation2D1D.txx @@ -80,6 +80,7 @@ namespace INTERP_KERNEL case Geometric2D: intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getPrecision(), InterpolationOptions::getOrientation()); diff --git a/src/INTERP_KERNEL/InterpolationOptions.cxx b/src/INTERP_KERNEL/InterpolationOptions.cxx index ebd37d1a1..d2677dcb3 100644 --- a/src/INTERP_KERNEL/InterpolationOptions.cxx +++ b/src/INTERP_KERNEL/InterpolationOptions.cxx @@ -29,6 +29,8 @@ const double INTERP_KERNEL::InterpolationOptions::DFT_SURF3D_ADJ_EPS=1.e-4; const double INTERP_KERNEL::InterpolationOptions::DFT_MAX_DIST_3DSURF_INTERSECT=-1.; +const double INTERP_KERNEL::InterpolationOptions::DFT_MIN_DOT_BTW_3DSURF_INTERSECT=-1.; + const char INTERP_KERNEL::InterpolationOptions::PRECISION_STR[]="Precision"; const char INTERP_KERNEL::InterpolationOptions::MEDIANE_PLANE_STR[]="MedianPlane"; @@ -39,6 +41,8 @@ const char INTERP_KERNEL::InterpolationOptions::BOUNDING_BOX_ADJ_ABS_STR[]="Boun const char INTERP_KERNEL::InterpolationOptions::MAX_DISTANCE_3DSURF_INSECT_STR[]="MaxDistance3DSurfIntersect"; +const char INTERP_KERNEL::InterpolationOptions::MIN_DOT_BTW_3DSURF_INSECT_STR[]="MinDotBetween3DSurfIntersect"; + const char INTERP_KERNEL::InterpolationOptions::PRINT_LEV_STR[]="PrintLevel"; const char INTERP_KERNEL::InterpolationOptions::DO_ROTATE_STR[]="DoRotate"; @@ -81,6 +85,7 @@ void INTERP_KERNEL::InterpolationOptions::init() _bounding_box_adjustment=DFT_SURF3D_ADJ_EPS; _bounding_box_adjustment_abs=0.; _max_distance_for_3Dsurf_intersect=DFT_MAX_DIST_3DSURF_INTERSECT; + _min_dot_btw_3Dsurf_intersect=DFT_MIN_DOT_BTW_3DSURF_INTERSECT; _orientation=0; _measure_abs=true; _splitting_policy=PLANAR_FACE_5; @@ -131,6 +136,11 @@ bool INTERP_KERNEL::InterpolationOptions::setOptionDouble(const std::string& key setMaxDistance3DSurfIntersect(value); return true; } + else if(key==MIN_DOT_BTW_3DSURF_INSECT_STR) + { + setMinDotBtwPlane3DSurfIntersect(value); + return true; + } else return false; } @@ -279,6 +289,7 @@ std::string INTERP_KERNEL::InterpolationOptions::printOptions() const oss << "Bounding box adj : " << _bounding_box_adjustment << std::endl; oss << "Bounding box adj abs : " << _bounding_box_adjustment_abs << std::endl; oss << "Max distance for 3DSurf intersect : " << _max_distance_for_3Dsurf_intersect << std::endl; + oss << "Min dot between plane for 3DSurf intersect : " << _min_dot_btw_3Dsurf_intersect << std::endl; oss << "Orientation : " << _orientation << std::endl; oss << "Measure abs : " << _measure_abs << std::endl; oss << "Splitting policy : " << getSplittingPolicyRepr() << std::endl; diff --git a/src/INTERP_KERNEL/InterpolationOptions.hxx b/src/INTERP_KERNEL/InterpolationOptions.hxx index 9b11b0ced..25a6a5e88 100644 --- a/src/INTERP_KERNEL/InterpolationOptions.hxx +++ b/src/INTERP_KERNEL/InterpolationOptions.hxx @@ -50,6 +50,7 @@ namespace INTERP_KERNEL //! this measure is absolute \b not relative to the cell size double _bounding_box_adjustment_abs ; double _max_distance_for_3Dsurf_intersect; + double _min_dot_btw_3Dsurf_intersect; int _orientation ; bool _measure_abs; SplittingPolicy _splitting_policy ; @@ -80,6 +81,9 @@ namespace INTERP_KERNEL double getMaxDistance3DSurfIntersect() const { return _max_distance_for_3Dsurf_intersect; } void setMaxDistance3DSurfIntersect(double bba) { _max_distance_for_3Dsurf_intersect=bba; } + double getMinDotBtwPlane3DSurfIntersect() const { return _min_dot_btw_3Dsurf_intersect; } + void setMinDotBtwPlane3DSurfIntersect(double v) { _min_dot_btw_3Dsurf_intersect=v; } + int getOrientation() const { return _orientation; } void setOrientation(int o) { _orientation=o; } @@ -116,12 +120,14 @@ namespace INTERP_KERNEL static const double DFT_MEDIAN_PLANE; static const double DFT_SURF3D_ADJ_EPS; static const double DFT_MAX_DIST_3DSURF_INTERSECT; + static const double DFT_MIN_DOT_BTW_3DSURF_INTERSECT; public: static const char PRECISION_STR[]; static const char MEDIANE_PLANE_STR[]; static const char BOUNDING_BOX_ADJ_STR[]; static const char BOUNDING_BOX_ADJ_ABS_STR[]; static const char MAX_DISTANCE_3DSURF_INSECT_STR[]; + static const char MIN_DOT_BTW_3DSURF_INSECT_STR[]; static const char PRINT_LEV_STR[]; static const char DO_ROTATE_STR[]; static const char ORIENTATION_STR[]; diff --git a/src/INTERP_KERNEL/InterpolationPlanar.txx b/src/INTERP_KERNEL/InterpolationPlanar.txx index 73b2e9d31..7666d5f91 100644 --- a/src/INTERP_KERNEL/InterpolationPlanar.txx +++ b/src/INTERP_KERNEL/InterpolationPlanar.txx @@ -164,6 +164,7 @@ namespace INTERP_KERNEL intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, InterpolationOptions::getPrecision(), InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getOrientation(), InterpolationOptions::getPrintLevel()); @@ -172,6 +173,7 @@ namespace INTERP_KERNEL intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, InterpolationOptions::getPrecision(), InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getDoRotate(), InterpolationOptions::getOrientation(), @@ -180,6 +182,7 @@ namespace INTERP_KERNEL case Geometric2D: intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getPrecision(), InterpolationOptions::getOrientation()); @@ -187,6 +190,7 @@ namespace INTERP_KERNEL case PointLocator: intersector=new PointLocator2DIntersector(myMeshT, myMeshS, _dim_caracteristic, InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getPrecision(), InterpolationOptions::getOrientation()); @@ -203,6 +207,7 @@ namespace INTERP_KERNEL intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, InterpolationOptions::getPrecision(), InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getOrientation(), InterpolationOptions::getPrintLevel()); @@ -211,6 +216,7 @@ namespace INTERP_KERNEL intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, InterpolationOptions::getPrecision(), InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getDoRotate(), InterpolationOptions::getOrientation(), @@ -219,6 +225,7 @@ namespace INTERP_KERNEL case Geometric2D: intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getPrecision(), InterpolationOptions::getOrientation()); @@ -226,6 +233,7 @@ namespace INTERP_KERNEL case PointLocator: intersector=new PlanarIntersectorP0P1PL(myMeshT, myMeshS, _dim_caracteristic, InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getPrecision(), InterpolationOptions::getOrientation()); @@ -234,6 +242,7 @@ namespace INTERP_KERNEL intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, InterpolationOptions::getPrecision(), InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getOrientation(), InterpolationOptions::getPrintLevel()); @@ -241,6 +250,7 @@ namespace INTERP_KERNEL case BarycentricGeo2D: intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getPrecision(), InterpolationOptions::getOrientation()); @@ -257,6 +267,7 @@ namespace INTERP_KERNEL intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, InterpolationOptions::getPrecision(), InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getOrientation(), InterpolationOptions::getPrintLevel()); @@ -265,6 +276,7 @@ namespace INTERP_KERNEL intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, InterpolationOptions::getPrecision(), InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getDoRotate(), InterpolationOptions::getOrientation(), @@ -273,21 +285,24 @@ namespace INTERP_KERNEL case Geometric2D: intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getPrecision(), InterpolationOptions::getOrientation()); break; case PointLocator: intersector=new PlanarIntersectorP1P0PL(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); break; case Barycentric: intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, InterpolationOptions::getPrecision(), InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getOrientation(), InterpolationOptions::getPrintLevel()); @@ -295,6 +310,7 @@ namespace INTERP_KERNEL case BarycentricGeo2D: intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getPrecision(), InterpolationOptions::getOrientation()); @@ -309,6 +325,7 @@ namespace INTERP_KERNEL intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, InterpolationOptions::getPrecision(), InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getOrientation(), InterpolationOptions::getPrintLevel()); @@ -317,6 +334,7 @@ namespace INTERP_KERNEL intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, InterpolationOptions::getPrecision(), InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getDoRotate(), InterpolationOptions::getOrientation(), @@ -325,6 +343,7 @@ namespace INTERP_KERNEL case Geometric2D: intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getPrecision(), InterpolationOptions::getOrientation()); @@ -332,6 +351,7 @@ namespace INTERP_KERNEL case PointLocator: intersector=new PlanarIntersectorP1P1PL(myMeshT, myMeshS, _dim_caracteristic, InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), InterpolationOptions::getMedianPlane(), InterpolationOptions::getPrecision(), InterpolationOptions::getOrientation()); diff --git a/src/INTERP_KERNEL/InterpolationUtils.hxx b/src/INTERP_KERNEL/InterpolationUtils.hxx index 18d550d32..a9af02d21 100644 --- a/src/INTERP_KERNEL/InterpolationUtils.hxx +++ b/src/INTERP_KERNEL/InterpolationUtils.hxx @@ -734,7 +734,7 @@ namespace INTERP_KERNEL inline std::vector reconstruct_polygon(const std::vector& V) { - std::size_t taille=V.size(); + int taille((int)V.size()); //VB : why 6 ? @@ -749,7 +749,7 @@ namespace INTERP_KERNEL COS[0]=1.0; SIN[0]=0.0; //angle[0]=0.0; - for(std::size_t i=0; i Trigo=calcul_cos_et_sin(&Bary[0],&V[0],&V[2*(i+1)]); COS[i+1]=Trigo[0]; @@ -765,7 +765,7 @@ namespace INTERP_KERNEL Pt_ordonne.reserve(taille); // std::multimap Ordre; std::multimap,int, AngleLess> CosSin; - for(std::size_t i=0;i >( meshS, meshT ), - _intersector(meshT, meshT, 0,0,0,0,0,0 ) + _intersector(meshT, meshT, 0,0,0,0,0,0,0 ) { if ( MyCMeshType::MY_SPACEDIM != 2 || MyCMeshType::MY_MESHDIM != 2 || MyUMeshType::MY_SPACEDIM != 2 || MyUMeshType::MY_MESHDIM != 2 ) diff --git a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx b/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx index 21b3e929b..bf91c4d8f 100644 --- a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx +++ b/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx @@ -35,7 +35,7 @@ namespace INTERP_KERNEL static const NumberingPolicy numPol=MyMeshType::My_numPol; protected: Planar2D1DIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); public: int getNumberOfRowsOfResMatrix() const; int getNumberOfColsOfResMatrix() const; diff --git a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx b/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx index 46c2e05ff..bdbc0ac85 100644 --- a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx +++ b/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx @@ -26,9 +26,9 @@ namespace INTERP_KERNEL { template Planar2D1DIntersectorP0P0::Planar2D1DIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double medianPlane, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,doRotate,orientation,printLevel) + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) { } diff --git a/src/INTERP_KERNEL/PlanarIntersector.hxx b/src/INTERP_KERNEL/PlanarIntersector.hxx index ae9a85374..ffef31825 100644 --- a/src/INTERP_KERNEL/PlanarIntersector.hxx +++ b/src/INTERP_KERNEL/PlanarIntersector.hxx @@ -42,14 +42,14 @@ namespace INTERP_KERNEL typedef typename std::map > DuplicateFacesType; public: //! \addtogroup InterpKerGrpIntPlan @{ - PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); //! @} virtual ~PlanarIntersector(); void createBoundingBoxes(const MyMeshType& mesh, std::vector& bbox); void adjustBoundingBoxes(std::vector& bbox, double surf3DAdjustmentEps, double surf3DAdjustmentEpsAbs); inline void getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes); - static int projection(double *Coords_A, double *Coords_B, - int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double median_plane, bool do_rotate); + static int Projection(double *Coords_A, double *Coords_B, + int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double minDot3DSurf, double median_plane, bool do_rotate); virtual const DuplicateFacesType* getIntersectFaces() const { return NULL; @@ -75,6 +75,7 @@ namespace INTERP_KERNEL const MyMeshType& _meshS; double _dim_caracteristic; double _max_distance_3Dsurf_intersect; + double _min_dot_btw_3Dsurf_intersect; double _precision; double _median_plane; bool _do_rotate; diff --git a/src/INTERP_KERNEL/PlanarIntersector.txx b/src/INTERP_KERNEL/PlanarIntersector.txx index b8fe7aafc..711bb1e24 100644 --- a/src/INTERP_KERNEL/PlanarIntersector.txx +++ b/src/INTERP_KERNEL/PlanarIntersector.txx @@ -30,9 +30,9 @@ namespace INTERP_KERNEL { template - PlanarIntersector::PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): + PlanarIntersector::PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): _meshT(meshT),_meshS(meshS), - _dim_caracteristic(dimCaracteristic),_max_distance_3Dsurf_intersect(md3DSurf),_precision(precision),_median_plane(medianPlane), + _dim_caracteristic(dimCaracteristic),_max_distance_3Dsurf_intersect(md3DSurf),_min_dot_btw_3Dsurf_intersect(minDot3DSurf),_precision(precision),_median_plane(medianPlane), _do_rotate(doRotate),_orientation(orientation),_print_level(printLevel) { _connectT=meshT.getConnectivityPtr(); @@ -275,12 +275,12 @@ namespace INTERP_KERNEL template int PlanarIntersector::projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB) { - return projection(Coords_A,Coords_B,nb_NodesA,nb_NodesB,_dim_caracteristic*_precision,_max_distance_3Dsurf_intersect,_median_plane,_do_rotate); + return Projection(Coords_A,Coords_B,nb_NodesA,nb_NodesB,_dim_caracteristic*_precision,_max_distance_3Dsurf_intersect,_min_dot_btw_3Dsurf_intersect,_median_plane,_do_rotate); } template - int PlanarIntersector::projection(double *Coords_A, double *Coords_B, - int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double median_plane, bool do_rotate) + int PlanarIntersector::Projection(double *Coords_A, double *Coords_B, + int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double minDot3DSurf, double median_plane, bool do_rotate) { double normal_A[3]={0,0,0}; double normal_B[3]={0,0,0}; @@ -289,11 +289,12 @@ namespace INTERP_KERNEL bool same_orientation; //Find the normal to cells A and B - int i_A1=1; - while(i_A1(Coords_A,&Coords_A[SPACEDIM*i_A1])< epsilon) i_A1++; - int i_A2=i_A1+1; + int i_A1(1); + while(i_A1(Coords_A,&Coords_A[SPACEDIM*i_A1])< epsilon) + i_A1++; + int i_A2(i_A1+1); crossprod(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); - double normA = sqrt(dotprod(normal_A,normal_A)); + double normA(sqrt(dotprod(normal_A,normal_A))); while(i_A2(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); @@ -301,11 +302,12 @@ namespace INTERP_KERNEL normA = sqrt(dotprod(normal_A,normal_A)); } - int i_B1=1; - while(i_B1(Coords_B,Coords_B+SPACEDIM*i_B1)< epsilon) i_B1++; - int i_B2=i_B1+1; + int i_B1(1); + while(i_B1(Coords_B,Coords_B+SPACEDIM*i_B1)< epsilon) + i_B1++; + int i_B2(i_B1+1); crossprod(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); - double normB = sqrt(dotprod(normal_B,normal_B)); + double normB(sqrt(dotprod(normal_B,normal_B))); while(i_B2(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); @@ -317,7 +319,7 @@ namespace INTERP_KERNEL if(md3DSurf>0.) { double coords_GA[3]; - for (int i=0;i<3;i++) + for(int i=0;i<3;i++) { coords_GA[i]=0.; for (int j=0;jmd3DSurf) - return 0; + for(int i=0;i<3;i++) + { + G1[i]=Coords_B[i]-coords_GA[i]; + G2[i]=Coords_B[i+3]-coords_GA[i]; + G3[i]=Coords_B[i+6]-coords_GA[i]; + } + double prodvect[3]; + prodvect[0]=G1[1]*G2[2]-G1[2]*G2[1]; + prodvect[1]=G1[2]*G2[0]-G1[0]*G2[2]; + prodvect[2]=G1[0]*G2[1]-G1[1]*G2[0]; + double prodscal=prodvect[0]*G3[0]+prodvect[1]*G3[1]+prodvect[2]*G3[2]; + if(fabs(prodscal)>md3DSurf) + return 0; } if(i_A2(normal_A,normal_B)>=0; + + double dotProd(dotprod(normal_A,normal_B)/(normA*normB)); + + if(fabs(dotProd)=0); if(!same_orientation) - for(int idim =0; idim< SPACEDIM; idim++) normal_A[idim] *=-1; + for(int idim =0; idim< SPACEDIM; idim++) + normal_A[idim] *=-1; - double normBB= sqrt(dotprod(normal_B,normal_B)); + double normBB(sqrt(dotprod(normal_B,normal_B))); for(int idim =0; idim< SPACEDIM; idim++) linear_comb[idim] = median_plane*normal_A[idim]/normA + (1-median_plane)*normal_B[idim]/normBB; double norm= sqrt(dotprod(linear_comb,linear_comb)); //Necessarily: norm>epsilon, no need to check - for(int idim =0; idim< SPACEDIM; idim++) linear_comb[idim]/=norm; + for(int idim =0; idim< SPACEDIM; idim++) + linear_comb[idim]/=norm; //Project the nodes of A and B on the median plane for(int i_A=0; i_A(&Coords_B[0],&Coords_B[i_B1])= " << distance2(Coords_B,Coords_B+i_B1) << std::endl; std::cout << "normal_B = " << normal_B[0] << " ; " << normal_B[1] << " ; " << normal_B[2] << std::endl; - return 1; } } diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx index 8f2db805f..8250348fb 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx @@ -34,7 +34,7 @@ namespace INTERP_KERNEL typedef typename MyMeshType::MyConnType ConnType; static const NumberingPolicy numPol=MyMeshType::My_numPol; protected: - PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); public: int getNumberOfRowsOfResMatrix() const; int getNumberOfColsOfResMatrix() const; diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx index 0abe6788f..55e58b382 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx @@ -26,9 +26,9 @@ namespace INTERP_KERNEL { template PlanarIntersectorP0P0::PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double medianPlane, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,doRotate,orientation,printLevel) + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) { } diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx index ebe8ec9c1..f2fdbd323 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx @@ -34,7 +34,7 @@ namespace INTERP_KERNEL typedef typename MyMeshType::MyConnType ConnType; static const NumberingPolicy numPol=MyMeshType::My_numPol; protected: - PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); public: void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); int getNumberOfRowsOfResMatrix() const; diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx index 45d6444dd..476d70a59 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx @@ -28,9 +28,9 @@ namespace INTERP_KERNEL { template PlanarIntersectorP0P1::PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double medianPlane, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,doRotate,orientation,printLevel) + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) { } diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx index 31ee76537..b64d19f9f 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx @@ -34,7 +34,7 @@ namespace INTERP_KERNEL typedef typename MyMeshType::MyConnType ConnType; static const NumberingPolicy numPol=MyMeshType::My_numPol; protected: - PlanarIntersectorP0P1Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + PlanarIntersectorP0P1Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); public: void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); int getNumberOfRowsOfResMatrix() const; diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx index b69294d2c..646f37893 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx @@ -29,10 +29,10 @@ namespace INTERP_KERNEL template PlanarIntersectorP0P1Bary::PlanarIntersectorP0P1Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, - double md3DSurf, double medianPlane, + double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf, - medianPlane,doRotate,orientation,printLevel) + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf, + medianPlane,doRotate,orientation,printLevel) { // SPEC: // "Limitation. For the P0P1 barycentric improvement only triangle target cells in 2D and diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx index dd3f5f4b7..d316639bd 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx @@ -34,7 +34,7 @@ namespace INTERP_KERNEL typedef typename MyMeshType::MyConnType ConnType; static const NumberingPolicy numPol=MyMeshType::My_numPol; public: - PlanarIntersectorP0P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double medianPlane, double precision, int orientation); + PlanarIntersectorP0P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); int getNumberOfRowsOfResMatrix() const; int getNumberOfColsOfResMatrix() const; diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx index 3cd1e2507..8eaff3d24 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx @@ -30,9 +30,9 @@ namespace INTERP_KERNEL { template PlanarIntersectorP0P1PL::PlanarIntersectorP0P1PL(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,true,orientation,0) + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) { } diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx index 13c1d74f9..4cfddd1cd 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx @@ -34,7 +34,7 @@ namespace INTERP_KERNEL typedef typename MyMeshType::MyConnType ConnType; static const NumberingPolicy numPol=MyMeshType::My_numPol; protected: - PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); public: void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); int getNumberOfRowsOfResMatrix() const; diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx index 55c743cc7..dff7880f7 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx @@ -27,9 +27,9 @@ namespace INTERP_KERNEL { template PlanarIntersectorP1P0::PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double medianPlane, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,doRotate,orientation,printLevel) + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) { } diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx index 523519044..0ae2625e2 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx @@ -34,7 +34,7 @@ namespace INTERP_KERNEL typedef typename MyMeshType::MyConnType ConnType; static const NumberingPolicy numPol=MyMeshType::My_numPol; protected: - PlanarIntersectorP1P0Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + PlanarIntersectorP1P0Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); public: void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); int getNumberOfRowsOfResMatrix() const; diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx index a0d992117..99b1bf068 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx @@ -31,9 +31,9 @@ namespace INTERP_KERNEL PLAN_INTER_TEMPLATE PLAN_INTERSECTOR::PlanarIntersectorP1P0Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, - double md3DSurf, double medianPlane, + double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf, + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf, medianPlane,doRotate,orientation,printLevel) { // SPEC: diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx index 88587588e..82b94afe1 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx @@ -34,7 +34,7 @@ namespace INTERP_KERNEL typedef typename MyMeshType::MyConnType ConnType; static const NumberingPolicy numPol=MyMeshType::My_numPol; public: - PlanarIntersectorP1P0PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double medianPlane, double precision, int orientation); + PlanarIntersectorP1P0PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); int getNumberOfRowsOfResMatrix() const; int getNumberOfColsOfResMatrix() const; diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx index 37de732d5..56ce75a67 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx @@ -32,9 +32,9 @@ namespace INTERP_KERNEL { template PlanarIntersectorP1P0PL::PlanarIntersectorP1P0PL(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,true,orientation,0) + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) { } diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx index 5751c5a99..c58b70e0c 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx @@ -34,7 +34,7 @@ namespace INTERP_KERNEL typedef typename MyMeshType::MyConnType ConnType; static const NumberingPolicy numPol=MyMeshType::My_numPol; protected: - PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); public: void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); int getNumberOfRowsOfResMatrix() const; diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx index a89468cf9..8431b3e9d 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx @@ -28,9 +28,9 @@ namespace INTERP_KERNEL { template PlanarIntersectorP1P1::PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double medianPlane, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,doRotate,orientation,printLevel) + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) { } diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx index 371f4ae8c..4b39cfc7c 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx @@ -34,7 +34,7 @@ namespace INTERP_KERNEL typedef typename MyMeshType::MyConnType ConnType; static const NumberingPolicy numPol=MyMeshType::My_numPol; public: - PlanarIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double medianPlane, double precision, int orientation); + PlanarIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); int getNumberOfRowsOfResMatrix() const; int getNumberOfColsOfResMatrix() const; diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx index ee1f9c8d8..34259fe3f 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx @@ -31,9 +31,9 @@ namespace INTERP_KERNEL { template PlanarIntersectorP1P1PL::PlanarIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,medianPlane,true,orientation,0) + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) { } diff --git a/src/INTERP_KERNEL/PointLocator2DIntersector.hxx b/src/INTERP_KERNEL/PointLocator2DIntersector.hxx index 8da0ccf8a..c906d1076 100644 --- a/src/INTERP_KERNEL/PointLocator2DIntersector.hxx +++ b/src/INTERP_KERNEL/PointLocator2DIntersector.hxx @@ -41,7 +41,7 @@ namespace INTERP_KERNEL static const NumberingPolicy numPol=MyMeshType::My_numPol; public: PointLocator2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double medianPlane, double precision, int orientation); + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords); diff --git a/src/INTERP_KERNEL/PointLocator2DIntersector.txx b/src/INTERP_KERNEL/PointLocator2DIntersector.txx index 581d08c7c..2491ea756 100644 --- a/src/INTERP_KERNEL/PointLocator2DIntersector.txx +++ b/src/INTERP_KERNEL/PointLocator2DIntersector.txx @@ -38,9 +38,9 @@ namespace INTERP_KERNEL { INTERSECTOR_TEMPLATE PTLOC2D_INTERSECTOR::PointLocator2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double medianPlane, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation): - InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, medianPlane, true, orientation, 0) + InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, true, orientation, 0) { } diff --git a/src/INTERP_KERNEL/TriangulationIntersector.hxx b/src/INTERP_KERNEL/TriangulationIntersector.hxx index ae08664ed..f4a9be5cc 100644 --- a/src/INTERP_KERNEL/TriangulationIntersector.hxx +++ b/src/INTERP_KERNEL/TriangulationIntersector.hxx @@ -39,7 +39,7 @@ namespace INTERP_KERNEL static const NumberingPolicy numPol=MyMeshType::My_numPol; public: TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double medianPlane, int orientation, int printLevel); + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, int orientation, int printLevel); double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords); diff --git a/src/INTERP_KERNEL/TriangulationIntersector.txx b/src/INTERP_KERNEL/TriangulationIntersector.txx index 72eb7dd98..db7f68a2a 100644 --- a/src/INTERP_KERNEL/TriangulationIntersector.txx +++ b/src/INTERP_KERNEL/TriangulationIntersector.txx @@ -39,9 +39,9 @@ namespace INTERP_KERNEL { TRI_INTER_TEMPLATE TRI_INTERSECTOR::TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double DimCaracteristic, double Precision, double md3DSurf, + double DimCaracteristic, double Precision, double md3DSurf, double minDot3DSurf, double MedianPlane, int orientation, int PrintLevel) - :InterpType(meshT,meshS,DimCaracteristic, Precision, md3DSurf, + :InterpType(meshT,meshS,DimCaracteristic, Precision, md3DSurf, minDot3DSurf, MedianPlane, true, orientation, PrintLevel) { if(PlanarIntersector::_print_level >= 1) diff --git a/src/INTERP_KERNELTest/CMakeLists.txt b/src/INTERP_KERNELTest/CMakeLists.txt index 6d3bb0e07..6d531ada4 100644 --- a/src/INTERP_KERNELTest/CMakeLists.txt +++ b/src/INTERP_KERNELTest/CMakeLists.txt @@ -49,6 +49,7 @@ SET(InterpKernelTest_SOURCES UnitTetra3D2DIntersectionTest.cxx UnitTetraIntersectionBaryTest.cxx TestInterpKernelUtils.cxx + ThreeDSurfProjectionTest.cxx ) SET(TestINTERP_KERNEL_SOURCES diff --git a/src/INTERP_KERNELTest/CppUnitTest.hxx b/src/INTERP_KERNELTest/CppUnitTest.hxx index 549541a3b..48a1811a1 100644 --- a/src/INTERP_KERNELTest/CppUnitTest.hxx +++ b/src/INTERP_KERNELTest/CppUnitTest.hxx @@ -22,10 +22,12 @@ #include +#include "InterpKernelTestExport.hxx" + /** * \brief Class tested by TestBogusClass : not very useful */ -class BogusClass { +class INTERPKERNELTEST_EXPORT BogusClass { friend class TestBogusClass; public: @@ -41,7 +43,7 @@ private: * \brief Class used to figure out CppUnit : not very useful * */ -class TestBogusClass : public CppUnit::TestFixture +class INTERPKERNELTEST_EXPORT TestBogusClass : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( TestBogusClass ); diff --git a/src/INTERP_KERNELTest/TestInterpKernel.cxx b/src/INTERP_KERNELTest/TestInterpKernel.cxx index cb6c907be..87d2dbb1c 100644 --- a/src/INTERP_KERNELTest/TestInterpKernel.cxx +++ b/src/INTERP_KERNELTest/TestInterpKernel.cxx @@ -32,6 +32,7 @@ #include "MultiElement2DTests.hxx" #include "MultiElementTetraTests.hxx" #include "SingleElementTetraTests.hxx" +#include "ThreeDSurfProjectionTest.hxx" using namespace INTERP_TEST; @@ -51,7 +52,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION( HexaTests ); CPPUNIT_TEST_SUITE_REGISTRATION( MultiElement2DTests ); CPPUNIT_TEST_SUITE_REGISTRATION( MultiElementTetraTests ); CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementTetraTests ); - +CPPUNIT_TEST_SUITE_REGISTRATION( ThreeDSurfProjectionTest ); // --- generic Main program from KERNEL_SRC/src/Basics/Test #include "BasicMainTest.hxx" diff --git a/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx b/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx new file mode 100644 index 000000000..461033382 --- /dev/null +++ b/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx @@ -0,0 +1,128 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "ThreeDSurfProjectionTest.hxx" +#include "PlanarIntersector.txx" + +class MyMeshType +{ +public: + static const int MY_SPACEDIM=3; + static const int MY_MESHDIM=3; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; + typedef int MyConnType; +}; + +class MyMatrixType +{ +}; + +void INTERP_TEST::ThreeDSurfProjectionTest::test1() +{ + // Two triangles coo and coo2 are perfectly // each others with a distance equal to 1e-6. + // A little rotation to make it more funny. + //coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) + //eps=1e-6 + //coo2=DataArrayDouble([0.,0.,eps,1.,0.,eps,0.,1.,eps],3,3) + //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[2.,1.,3.],0.3,coo) + //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[2.,1.,3.],0.3,coo2) + const double coo[9]={0.,0.,0.,0.96809749223257568,0.24332379388106262,-0.059839592782071335,-0.23056279077409292,0.95852673990234838,0.16753294721527912}; + const double coo2[9]={9.8122602102980502e-08,-1.4839144255482456e-7,9.8404874611628791e-7,0.96809759035517784,0.24332364548962007,-0.059838608733325221,-0.23056269265149082,0.9585265915109058,0.16753393126402524}; + double *tmp0(new double[9]),*tmp1(new double[9]); + int ret; + //eps=1e-2. eps is a tolerance to detect that two points are the same or not in a same polygon. + // here the max 3D distance is 1e-5 > 1e-6 so 1 is expected + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(1,ret); + const double expected0[9]={0.,0.,0.,1.,0.,0.,0.,1.,0.}; + for(int i=0;i<9;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected0[i],tmp0[i],1e-15); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected0[i],tmp1[i],1e-15); + } + // here the max 3D distance is 1e-8 < 1e-6 so 0 is expected + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-8/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(0,ret); + // here testing when max 3D distance is 1e-5 > 1e-6 with inverted cells + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+3,tmp1+6); std::copy(coo2+3,coo2+6,tmp1+3); std::copy(coo2+6,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(-1,ret); + const double expected1[9]={-0.7071067811865476,-0.7071067811865476,0.,0.,-1.4142135623730951,0.,-1.4142135623730951,-1.4142135623730951,0.}; + const double expected2[9]={-1.4142135623730951,-1.4142135623730951,0.,0.,-1.4142135623730951,0.,-0.7071067811865476,-0.7071067811865476,0.}; + for(int i=0;i<9;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],tmp0[i],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],tmp1[i],1e-14); + } + // + delete [] tmp0; + delete [] tmp1; +} + +void INTERP_TEST::ThreeDSurfProjectionTest::test2() +{// here the two triangles have their center of inertia very close (eps) but the angle between the two planes is "big" + //coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) + //coocpy=coo.deepCpy() + //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[-1,-1.,0.],pi/3,coocpy) + //coocpy+=[eps*sqrt(3)/2,eps/2,eps*0.] + // + const double coo[9]={0.,0.,0.,0.96809749223257568,0.24332379388106262,-0.059839592782071335,-0.23056279077409292,0.95852673990234838,0.16753294721527912}; + const double coo2[9]={7.2311562622637225e-07,6.8998795679738294e-07,3.1943866106249849e-08,0.72852072144314628,0.33125439126063028,0.5996079016637561,0.0090154262465889021,0.87059752249869415,-0.49191448334281612}; + double *tmp0(new double[9]),*tmp1(new double[9]); + int ret; + //eps=1e-2. eps is a tolerance to detect that two points are the same or not in a same polygon. + // here the max 3D distance is 1e-5 > 1e-6 so 1 is expected + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(1,ret); + // here the max 3D distance is 1e-8 < 1e-6 so 0 is expected + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-8/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(0,ret); + // again max 3D distance is 1e-5 > 1e-6 so 1 is expected + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(1,ret); + // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.8. 0 expected. because the angle is pi/4 so cos(pi/3) > 0.8 + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.8/* <- */,0.5,true); + CPPUNIT_ASSERT_EQUAL(0,ret); + // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.7. 1 expected. because the angle is pi/4 so cos(pi/3) < 0.49 + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.49/* <- */,0.5,true); + CPPUNIT_ASSERT_EQUAL(1,ret); + // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.7. 0 expected. because the angle is pi/4 so cos(pi/3) > 0.51 + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.51/* <- */,0.5,true); + CPPUNIT_ASSERT_EQUAL(0,ret); + // + delete [] tmp0; + delete [] tmp1; +} diff --git a/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx b/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx new file mode 100644 index 000000000..77432d072 --- /dev/null +++ b/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __THREEDSURFPROJECTIONTEST_HXX__ +#define __THREEDSURFPROJECTIONTEST_HXX__ + +#include + +#include "InterpKernelTestExport.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class dedicated of the test of the preprocessing of 3D surf cells before performing invoking 2D algorithms. + */ + class INTERPKERNELTEST_EXPORT ThreeDSurfProjectionTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( ThreeDSurfProjectionTest ); + CPPUNIT_TEST ( test1 ); + CPPUNIT_TEST ( test2 ); + CPPUNIT_TEST_SUITE_END(); + public: + void test1(); + void test2(); + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx index b928c5d87..06876f548 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -467,8 +467,10 @@ std::string MEDCouplingCMesh::advancedRepr() const * referred by \a this mesh. * \throw If \a i is not one of [0,1,2]. * + * \if ENABLE_EXAMPLES * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
* \ref py_mccmesh_getCoordsAt "Here is a Python example". + * \endif */ const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const { @@ -493,8 +495,10 @@ const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const * referred by \a this mesh. * \throw If \a i is not one of [0,1,2]. * + * \if ENABLE_EXAMPLES * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
* \ref py_mccmesh_getCoordsAt "Here is a Python example". + * \endif */ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) { @@ -520,8 +524,10 @@ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) * \throw If \a arr->getNumberOfComponents() != 1. * \throw If \a i is not one of [0,1,2]. * + * \if ENABLE_EXAMPLES * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
* \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". + * \endif */ void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) { @@ -553,8 +559,10 @@ void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) * axis. It must be an array of one component or \c NULL. * \throw If \a coords*->getNumberOfComponents() != 1. * + * \if ENABLE_EXAMPLES * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
* \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". + * \endif */ void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ) { diff --git a/src/MEDCoupling/MEDCouplingField.hxx b/src/MEDCoupling/MEDCouplingField.hxx index d857aceb9..10ba25e16 100644 --- a/src/MEDCoupling/MEDCouplingField.hxx +++ b/src/MEDCoupling/MEDCouplingField.hxx @@ -53,6 +53,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT virtual void copyTinyStringsFrom(const MEDCouplingField *other); MEDCOUPLING_EXPORT void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh); MEDCOUPLING_EXPORT const ParaMEDMEM::MEDCouplingMesh *getMesh() const { return _mesh; } + MEDCOUPLING_EXPORT ParaMEDMEM::MEDCouplingMesh *getMesh() { return const_cast(_mesh); } MEDCOUPLING_EXPORT void setName(const std::string& name) { _name=name; } MEDCOUPLING_EXPORT std::string getDescription() const { return _desc; } MEDCOUPLING_EXPORT void setDescription(const std::string& desc) { _desc=desc; } diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx index 4790b4cb9..05fe947f2 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx @@ -65,6 +65,7 @@ const char MEDCouplingFieldDiscretizationKriging::REPR[]="KRIGING"; const TypeOfField MEDCouplingFieldDiscretizationKriging::TYPE=ON_NODES_KR; // doc is here http://www.code-aster.org/V2/doc/default/fr/man_r/r3/r3.01.01.pdf +const double MEDCouplingFieldDiscretizationGaussNE::FGP_POINT1[1]={0.}; const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG2[2]={1.,1.}; const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG3[3]={0.5555555555555556,0.8888888888888888,0.5555555555555556}; const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG4[4]={0.347854845137454,0.347854845137454,0.652145154862546,0.652145154862546}; @@ -75,10 +76,14 @@ const double MEDCouplingFieldDiscretizationGaussNE::FGP_QUAD4[4]={1.,1.,1.,1.}; const double MEDCouplingFieldDiscretizationGaussNE::FGP_QUAD8[8]={1.,1.,1.,1.,1.,1.,1.,1.}; const double MEDCouplingFieldDiscretizationGaussNE::FGP_QUAD9[9]={0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234}; const double MEDCouplingFieldDiscretizationGaussNE::FGP_TETRA4[4]={0.041666666666666664,0.041666666666666664,0.041666666666666664,0.041666666666666664}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_TETRA10[10]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check const double MEDCouplingFieldDiscretizationGaussNE::FGP_PENTA6[6]={0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_PENTA15[15]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA8[8]={1.,1.,1.,1.,1.,1.,1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA27[27]={0.1714677640603567,0.1714677640603567,0.1714677640603567,0.1714677640603567,0.1714677640603567,0.1714677640603567,0.1714677640603567,0.1714677640603567,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.43895747599451296,0.43895747599451296,0.43895747599451296,0.43895747599451296,0.43895747599451296,0.43895747599451296,0.7023319615912208}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA20[20]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA27[27]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.}; const double MEDCouplingFieldDiscretizationGaussNE::FGP_PYRA5[5]={0.13333333333333333,0.13333333333333333,0.13333333333333333,0.13333333333333333,0.13333333333333333}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_PYRA13[13]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG2[2]={-1.,1.}; const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG3[3]={-1.,1.,0.}; const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG4[4]={-1.,1.,-0.3333333333333333,0.3333333333333333}; @@ -94,9 +99,9 @@ const double MEDCouplingFieldDiscretizationGaussNE::REF_PENTA6[18]={-1.,1.,0.,-1 const double MEDCouplingFieldDiscretizationGaussNE::REF_PENTA15[45]={-1.,1.,0.,-1.,0.,1.,-1.,0.,0.,1.,1.,0.,1.,0.,1.,1.,0.,0.,-1.,0.5,0.5,-1.,0.,0.5,-1.,0.5,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.5,0.5,1.,0.,0.5,1.,0.5,0.}; const double MEDCouplingFieldDiscretizationGaussNE::REF_HEXA8[24]={-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.,-1.,1.,-1.,-1.,-1.,1.,1.,-1.,1.,1.,1.,1.,-1.,1.,1.}; const double MEDCouplingFieldDiscretizationGaussNE::REF_HEXA20[60]={-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.,-1.,1.,-1.,-1.,-1.,1.,1.,-1.,1.,1.,1.,1.,-1.,1.,1.,0.,-1.,-1.,1.,0.,-1.,0.,1.,-1.,-1.,0.,-1.,-1.,-1.,0.,1.,-1.,0.,1.,1.,0.,-1.,1.,0.,0.,-1.,1.,1.,0.,1.,0.,1.,1.,-1.,0.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_HEXA27[81]={-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.,-1.,1.,-1.,-1.,-1.,1.,1.,-1.,1.,1.,1.,1.,-1.,1.,1.,0.,-1.,-1.,1.,0.,-1.,0.,1.,-1.,-1.,0.,-1.,-1.,-1.,0.,1.,-1.,0.,1.,1.,0.,-1.,1.,0.,0.,-1.,1.,1.,0.,1.,0.,1.,1.,-1.,0.,1.,0.,0.,-1.,0.,-1.,0.,1.,0.,0.,0.,1.,0.,-1.,0.,0.,0.,0.,1.,0.,0.,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_HEXA27[81]={-1.,-1.,-1.,-1.,1.,-1.,1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,-1.,1.,1.,1.,1.,1.,1.,-1.,1.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.}; const double MEDCouplingFieldDiscretizationGaussNE::REF_PYRA5[15]={1.,0.,0.,0.,1.,0.,-1.,0.,0.,0.,-1.,0.,0.,0.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_PYRA13[39]={1.,0.,0.,0.,1.,0.,-1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.5,0.5,0.,-0.5,0.5,0.,-0.5,-0.5,0.,0.5,-0.5,0.,0.5,0.,0.5,0.,0.5,0.5,-0.5,0.,0.5,0.,-0.5,0.5}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_PYRA13[39]={1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,1.,0.5,-0.5,0.,-0.5,-0.5,0.,-0.5,0.5,0.,0.5,0.5,0.,0.5,0.,0.5,0.,-0.5,0.5,-0.5,0.,0.5,0.,0.5,0.5}; const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG2[2]={0.577350269189626,-0.577350269189626}; const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG3[3]={-0.774596669241,0.,0.774596669241}; const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG4[4]={0.339981043584856,-0.339981043584856,0.861136311594053,-0.861136311594053}; @@ -107,10 +112,14 @@ const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD4[8]={-0.77459666924 const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD8[16]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.,-0.774596669241483,0.774596669241483,0.,0.,0.774596669241483,-0.774596669241483,0.}; const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD9[18]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.,-0.774596669241483,0.774596669241483,0.,0.,0.774596669241483,-0.774596669241483,0.,0.,0.}; const double MEDCouplingFieldDiscretizationGaussNE::LOC_TETRA4[12]={0.1381966011250105,0.1381966011250105,0.1381966011250105,0.1381966011250105,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.1381966011250105}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_TETRA10[30]={0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,0.5,0.5,0.,0.,0.5,0.,0.5,0.,0.5,0.5,0.,0.5,0.,0.5,0.5,0.,0.};//to check const double MEDCouplingFieldDiscretizationGaussNE::LOC_PENTA6[18]={-0.5773502691896258,0.5,0.5,-0.5773502691896258,0.,0.5,-0.5773502691896258,0.5,0.,0.5773502691896258,0.5,0.5,0.5773502691896258,0.,0.5,0.5773502691896258,0.5,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_PENTA15[45]={-1.,1.,0.,-1.,0.,1.,-1.,0.,0.,1.,1.,0.,1.,0.,1.,1.,0.,0.,-1.,0.5,0.5,-1.,0.,0.5,-1.,0.5,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.5,0.5,1.,0.,0.5,1.,0.5,0.};//to check const double MEDCouplingFieldDiscretizationGaussNE::LOC_HEXA8[24]={-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_HEXA27[81]={-0.7745966692414834,-0.7745966692414834,-0.7745966692414834,-0.7745966692414834,-0.7745966692414834,0.,-0.7745966692414834,-0.7745966692414834,0.7745966692414834,-0.7745966692414834,0.,-0.7745966692414834,-0.7745966692414834,0.,0.,-0.7745966692414834,0.,0.7745966692414834,-0.7745966692414834,0.7745966692414834,-0.7745966692414834,-0.7745966692414834,0.7745966692414834,0.,-0.7745966692414834,0.7745966692414834,0.7745966692414834,0.,-0.7745966692414834,-0.7745966692414834,0,-0.7745966692414834,0.,0.,-0.7745966692414834,0.7745966692414834,0.,0.,-0.7745966692414834,0.,0.,0.,0.,0.,0.7745966692414834,0.,0.7745966692414834,-0.7745966692414834,0.,0.7745966692414834,0.,0.,0.7745966692414834,0.7745966692414834,0.7745966692414834,-0.7745966692414834,-0.7745966692414834,0.7745966692414834,-0.7745966692414834,0.,0.7745966692414834,-0.7745966692414834,0.7745966692414834,0.7745966692414834,0,-0.7745966692414834,0.7745966692414834,0.,0.,0.7745966692414834,0.,0.7745966692414834,0.7745966692414834,0.7745966692414834,-0.7745966692414834,0.7745966692414834,0.7745966692414834,0.,0.7745966692414834,0.7745966692414834,0.7745966692414834}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_HEXA20[60]={-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.,-1.,1.,-1.,-1.,-1.,1.,1.,-1.,1.,1.,1.,1.,-1.,1.,1.,0.,-1.,-1.,1.,0.,-1.,0.,1.,-1.,-1.,0.,-1.,-1.,-1.,0.,1.,-1.,0.,1.,1.,0.,-1.,1.,0.,0.,-1.,1.,1.,0.,1.,0.,1.,1.,-1.,0.,1.};//to check +const double MEDCouplingFieldDiscretizationGaussNE::LOC_HEXA27[81]={-1.,-1.,-1.,-1.,1.,-1.,1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,-1.,1.,1.,1.,1.,1.,1.,-1.,1.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.}; const double MEDCouplingFieldDiscretizationGaussNE::LOC_PYRA5[15]={0.5,0.,0.1531754163448146,0.,0.5,0.1531754163448146,-0.5,0.,0.1531754163448146,0.,-0.5,0.1531754163448146,0.,0.,0.6372983346207416}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_PYRA13[39]={1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,0.999999999999,0.5,-0.5,0.,-0.5,-0.5,0.,-0.5,0.5,0.,0.5,0.5,0.,0.5,0.,0.5,0.,-0.5,0.5,-0.5,0.,0.5,0.,0.5,0.5};//to check 0.99999... to avoid nan ! on node #4 of PYRA13 MEDCouplingFieldDiscretization::MEDCouplingFieldDiscretization():_precision(DFLT_PRECISION) { @@ -2269,6 +2278,9 @@ const double *MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometric { switch(geoType) { + case INTERP_KERNEL::NORM_POINT1: + lgth=(int)sizeof(FGP_POINT1)/sizeof(double); + return FGP_POINT1; case INTERP_KERNEL::NORM_SEG2: lgth=(int)sizeof(FGP_SEG2)/sizeof(double); return FGP_SEG2; @@ -2299,20 +2311,32 @@ const double *MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometric case INTERP_KERNEL::NORM_TETRA4: lgth=(int)sizeof(FGP_TETRA4)/sizeof(double); return FGP_TETRA4; + case INTERP_KERNEL::NORM_TETRA10: + lgth=(int)sizeof(FGP_TETRA10)/sizeof(double); + return FGP_TETRA10; case INTERP_KERNEL::NORM_PENTA6: lgth=(int)sizeof(FGP_PENTA6)/sizeof(double); return FGP_PENTA6; + case INTERP_KERNEL::NORM_PENTA15: + lgth=(int)sizeof(FGP_PENTA15)/sizeof(double); + return FGP_PENTA15; case INTERP_KERNEL::NORM_HEXA8: lgth=(int)sizeof(FGP_HEXA8)/sizeof(double); return FGP_HEXA8; + case INTERP_KERNEL::NORM_HEXA20: + lgth=(int)sizeof(FGP_HEXA20)/sizeof(double); + return FGP_HEXA20; case INTERP_KERNEL::NORM_HEXA27: lgth=(int)sizeof(FGP_HEXA27)/sizeof(double); return FGP_HEXA27; case INTERP_KERNEL::NORM_PYRA5: lgth=(int)sizeof(FGP_PYRA5)/sizeof(double); return FGP_PYRA5; + case INTERP_KERNEL::NORM_PYRA13: + lgth=(int)sizeof(FGP_PYRA13)/sizeof(double); + return FGP_PYRA13; default: - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometricType : only SEG[2,3,4], TRI[3,6,7], QUAD[4,9], TETRA4, PENTA6, HEXA[8,27], PYRA5 supported !"); + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometricType : only SEG[2,3,4], TRI[3,6,7], QUAD[4,9], TETRA[4,10], PENTA[6,15], HEXA[8,20,27], PYRA[5,13] supported !"); } } @@ -2320,6 +2344,9 @@ const double *MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricTy { switch(geoType) { + case INTERP_KERNEL::NORM_POINT1: + lgth=0; + return 0; case INTERP_KERNEL::NORM_SEG2: lgth=(int)sizeof(REF_SEG2)/sizeof(double); return REF_SEG2; @@ -2383,6 +2410,11 @@ const double *MEDCouplingFieldDiscretizationGaussNE::GetLocsFromGeometricType(IN { switch(geoType) { + case INTERP_KERNEL::NORM_POINT1: + { + lgth=0; + return 0; + } case INTERP_KERNEL::NORM_SEG2: { lgth=(int)sizeof(LOC_SEG2)/sizeof(double); @@ -2433,16 +2465,31 @@ const double *MEDCouplingFieldDiscretizationGaussNE::GetLocsFromGeometricType(IN lgth=(int)sizeof(LOC_TETRA4)/sizeof(double); return LOC_TETRA4; } + case INTERP_KERNEL::NORM_TETRA10: + { + lgth=(int)sizeof(LOC_TETRA10)/sizeof(double); + return LOC_TETRA10; + } case INTERP_KERNEL::NORM_PENTA6: { lgth=(int)sizeof(LOC_PENTA6)/sizeof(double); return LOC_PENTA6; } + case INTERP_KERNEL::NORM_PENTA15: + { + lgth=(int)sizeof(LOC_PENTA15)/sizeof(double); + return LOC_PENTA15; + } case INTERP_KERNEL::NORM_HEXA8: { lgth=(int)sizeof(LOC_HEXA8)/sizeof(double); return LOC_HEXA8; } + case INTERP_KERNEL::NORM_HEXA20: + { + lgth=(int)sizeof(LOC_HEXA20)/sizeof(double); + return LOC_HEXA20; + } case INTERP_KERNEL::NORM_HEXA27: { lgth=(int)sizeof(LOC_HEXA27)/sizeof(double); @@ -2453,6 +2500,11 @@ const double *MEDCouplingFieldDiscretizationGaussNE::GetLocsFromGeometricType(IN lgth=(int)sizeof(LOC_PYRA5)/sizeof(double); return LOC_PYRA5; } + case INTERP_KERNEL::NORM_PYRA13: + { + lgth=(int)sizeof(LOC_PYRA13)/sizeof(double); + return LOC_PYRA13; + } default: throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::GetLocsFromGeometricType : only SEG[2,3,4], TRI[3,6,7], QUAD[4,8,9], TETRA[4,10], PENTA[6,15], HEXA[8,20,27], PYRA[5,13] supported !"); } diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx index 599747830..37f0a053c 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx @@ -335,6 +335,7 @@ namespace ParaMEDMEM public: static const char REPR[]; static const TypeOfField TYPE; + static const double FGP_POINT1[1]; static const double FGP_SEG2[2]; static const double FGP_SEG3[3]; static const double FGP_SEG4[4]; @@ -345,13 +346,14 @@ namespace ParaMEDMEM static const double FGP_QUAD8[8]; static const double FGP_QUAD9[9]; static const double FGP_TETRA4[4]; - //static const double FGP_TETRA10[10]; + static const double FGP_TETRA10[10];//to check static const double FGP_PENTA6[6]; - //static const double FGP_PENTA15[15]; + static const double FGP_PENTA15[15];//to check static const double FGP_HEXA8[8]; + static const double FGP_HEXA20[20];//to check static const double FGP_HEXA27[27]; static const double FGP_PYRA5[5]; - //static const double FGP_PYRA13[13]; + static const double FGP_PYRA13[13];//to check static const double REF_SEG2[2]; static const double REF_SEG3[3]; static const double REF_SEG4[4]; @@ -380,13 +382,14 @@ namespace ParaMEDMEM static const double LOC_QUAD8[16]; static const double LOC_QUAD9[18]; static const double LOC_TETRA4[12]; - //static const double LOC_TETRA10[30]; + static const double LOC_TETRA10[30];//to check static const double LOC_PENTA6[18]; - //static const double LOC_PENTA15[45]; + static const double LOC_PENTA15[45];//to check static const double LOC_HEXA8[24]; + static const double LOC_HEXA20[60];//to check static const double LOC_HEXA27[81]; static const double LOC_PYRA5[15]; - //static const double LOC_PYRA13[39]; + static const double LOC_PYRA13[39];//to check }; class MEDCouplingFieldDiscretizationKriging : public MEDCouplingFieldDiscretizationOnNodes diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index 1619b2984..7b91972ee 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -200,8 +200,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The * caller is to delete this field using decrRef() as it is no more needed. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_buildNewTimeReprFromThis "Here is a C++ example."
* \ref py_mcfielddouble_buildNewTimeReprFromThis "Here is a Python example." + * \endif * \sa clone() */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const @@ -596,8 +598,10 @@ bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble * * \throw If \a check == \c true and \a old2NewBg contains equal ids. * \throw If mesh nature does not allow renumbering (e.g. structured mesh). * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_renumberCells "Here is a C++ example".
* \ref py_mcfielddouble_renumberCells "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) { @@ -659,8 +663,10 @@ void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool * \throw If mesh nature does not allow renumbering (e.g. structured mesh). * \throw If values at merged nodes deffer more than \a eps. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".
* \ref py_mcfielddouble_renumberNodes "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps) { @@ -752,8 +758,10 @@ DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) co * \param [in] part - an array of cell ids to include to the result field. * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The caller is to delete this field using decrRef() as it is no more needed. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".
* \ref py_mcfielddouble_subpart1 "Here is a Python example". + * \endif * \sa MEDCouplingFieldDouble::buildSubPartRange */ @@ -791,8 +799,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt * * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \a this->getMesh(). * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
* \ref py_mcfielddouble_subpart1 "Here a Python example." + * \endif * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const @@ -1334,8 +1344,10 @@ void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const * \throw If the mesh is not set. * \throw If the mesh is not a structured one. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".
* \ref py_mcfielddouble_getValueOnPos "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const { @@ -1356,8 +1368,10 @@ void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) con * \throw If the mesh is not set. * \throw If \a spaceLoc is out of the spatial discretization. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".
* \ref py_mcfielddouble_getValueOn "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const { @@ -1382,8 +1396,10 @@ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) con * \throw If the mesh is not set. * \throw If any point in \a spaceLoc is out of the spatial discretization. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".
* \ref py_mcfielddouble_getValueOnMulti "Here is a Python example". + * \endif */ DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const { @@ -1407,8 +1423,10 @@ DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, * \throw If \a spaceLoc is out of the spatial discretization. * \throw If \a time is not covered by \a this->_time_discr. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".
* \ref py_mcfielddouble_getValueOn_time "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const { @@ -1466,7 +1484,9 @@ MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(IN * \throw If \a func returns \c false. * \throw If the spatial discretization of \a this field is NULL. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example". + * \endif */ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) { @@ -1510,8 +1530,10 @@ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate f * \throw If the spatial discretization of \a this field is NULL. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".
* \ref py_mcfielddouble_fillFromAnalytic "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) { @@ -1557,8 +1579,10 @@ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& f * \throw If the spatial discretization of \a this field is NULL. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".
* \ref py_mcfielddouble_fillFromAnalytic2 "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const std::string& func) { @@ -1604,8 +1628,10 @@ void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const std::string& * \throw If the spatial discretization of \a this field is NULL. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".
* \ref py_mcfielddouble_fillFromAnalytic3 "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const std::string& func) { @@ -1625,7 +1651,9 @@ void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector * \ref py_mcfielddouble_applyFunc_val "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val) { @@ -1681,8 +1711,10 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val) * This function is to compute a field value basing on a current field value. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".
* \ref py_mcfielddouble_applyFunc "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) { @@ -1719,8 +1751,10 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) * This function is to compute a new field value basing on a current field value. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".
* \ref py_mcfielddouble_applyFunc2 "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const std::string& func) { @@ -1756,8 +1790,10 @@ void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const std::string& func) * This function is to compute a new field value basing on a current field value. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".
* \ref py_mcfielddouble_applyFunc3 "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func) { @@ -1786,8 +1822,10 @@ void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector * \ref py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::applyFunc(const std::string& func) { @@ -2101,8 +2139,10 @@ void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector * \ref py_mcfielddouble_changeUnderlyingMesh "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps) { @@ -2115,7 +2155,7 @@ void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, renumberCellsWithoutMesh(cellCor->getConstPointer(),false); if(nodeCor) renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps); - setMesh(const_cast(other)); + setMesh(other); } /*! @@ -2147,8 +2187,10 @@ void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, * \throw If the two fields are not coherent for merge. * \throw If field values at merged nodes (if any) deffer more than \a eps. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".
* \ref py_mcfielddouble_substractInPlaceDM "Here is a Python example". + * \endif * \sa changeUnderlyingMesh(). */ void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps) @@ -2683,8 +2725,10 @@ void MEDCouplingFieldDouble::sortPerTuple(bool asc) * \throw If the spatial discretization of \a f1 is NULL. * \throw If the time discretization of \a f1 is NULL. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".
* \ref py_mcfielddouble_MergeFields "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) { @@ -2722,8 +2766,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFie * \throw If \a a is empty. * \throw If the fields are not compatible for the merge. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".
* \ref py_mcfielddouble_MergeFields "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector& a) { @@ -2857,8 +2903,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCoup * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they * differ not only in values. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".
* \ref py_mcfielddouble_MaxFields "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) { @@ -2885,8 +2933,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingField * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they * differ not only in values. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".
* \ref py_mcfielddouble_MaxFields "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) { @@ -3176,8 +3226,10 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCoupli * \throw If the mesh is not set. * \throw If any of the fields has no name. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".
* \ref py_mcfielddouble_WriteVTK "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector& fs, bool isBinary) { diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 0d5d059a0..ed49f5559 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -1846,7 +1846,9 @@ void DataArrayDouble::transpose() * \throw If a component index (\a i) is not valid: * \a i < 0 || \a i >= \a this->getNumberOfComponents(). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example". + * \endif */ DataArray *DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const { @@ -1879,9 +1881,11 @@ DataArray *DataArrayDouble::keepSelectedComponents(const std::vector& compo * \throw If \a this is not allocated. * \throw If \a this and \a other arrays have different number of tuples. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example". * * \ref py_mcdataarraydouble_meldwith "Here is a Python example". + * \endif */ void DataArrayDouble::meldWith(const DataArrayDouble *other) { @@ -1961,9 +1965,11 @@ bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, * \throw If \a this is not allocated. * \throw If the number of components is not in [1,2,3,4]. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example". * * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example". + * \endif * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe */ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const @@ -2190,7 +2196,9 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble * \throw If \a this is not allocated. * \throw If the number of components is not in [1,2,3,4]. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example". + * \endif */ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const { @@ -2214,7 +2222,9 @@ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTuple * \throw If \a compoIds.size() != \a a->getNumberOfComponents(). * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example". + * \endif */ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) { @@ -2264,7 +2274,9 @@ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std: * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example". + * \endif */ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) { @@ -2327,7 +2339,9 @@ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, i * non-empty range of increasing indices or indices are out of a valid range * for \this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example". + * \endif */ void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) { @@ -2381,7 +2395,9 @@ void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTupl * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or * a->getNumberOfComponents() != (endComp - bgComp). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example". + * \endif */ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) { @@ -2452,7 +2468,9 @@ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTu * \throw If any index of tuple/component given by bgTuples / bgComp is * out of a valid range for \a this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example". + * \endif */ void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) { @@ -2512,7 +2530,9 @@ void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, cons * non-empty range of increasing indices or indices are out of a valid range * for \this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example". + * \endif */ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) { @@ -2584,7 +2604,9 @@ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTu * non-empty range of increasing indices or indices are out of a valid range * for \this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example". + * \endif */ void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) { @@ -4525,8 +4547,10 @@ DataArrayDoubleIterator *DataArrayDouble::iterator() * * \sa DataArrayDouble::getIdsNotInRange * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".
* \ref py_mcdataarraydouble_getidsinrange "Here is a Python example". + * \endif */ DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const { @@ -6353,8 +6377,10 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int * The caller is to delete this result array using decrRef() as it is no more * needed. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".
* \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example". + * \endif */ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const { @@ -6418,9 +6444,11 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const * The caller is to delete this result array using decrRef() as it is no more * needed. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example". * * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example". + * \endif */ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const { @@ -6720,9 +6748,11 @@ void DataArrayInt::checkStrictlyMonotonic(bool increasing) const * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples(). * \throw If \a other includes a value which is not in \a this array. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example". * * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example". + * \endif */ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const { @@ -7605,7 +7635,9 @@ void DataArrayInt::reAlloc(int nbOfTuples) * \throw If a component index (\a i) is not valid: * \a i < 0 || \a i >= \a this->getNumberOfComponents(). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". + * \endif */ DataArray *DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const { @@ -7634,9 +7666,11 @@ DataArray *DataArrayInt::keepSelectedComponents(const std::vector& compoIds * \throw If \a this is not allocated. * \throw If \a this and \a other arrays have different number of tuples. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example". * * \ref py_mcdataarrayint_meldwith "Here is a Python example". + * \endif */ void DataArrayInt::meldWith(const DataArrayInt *other) { @@ -7677,7 +7711,9 @@ void DataArrayInt::meldWith(const DataArrayInt *other) * \throw If \a compoIds.size() != \a a->getNumberOfComponents(). * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example". + * \endif */ void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) { @@ -7728,7 +7764,9 @@ void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vecto * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". + * \endif */ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) { @@ -7791,7 +7829,9 @@ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int end * non-empty range of increasing indices or indices are out of a valid range * for \this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example". + * \endif */ void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) { @@ -7846,7 +7886,9 @@ void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, in * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or * a->getNumberOfComponents() != (endComp - bgComp). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". + * \endif */ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) { @@ -7917,7 +7959,9 @@ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, * \throw If any index of tuple/component given by bgTuples / bgComp is * out of a valid range for \a this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". + * \endif */ void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) { @@ -7977,7 +8021,9 @@ void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int * non-empty range of increasing indices or indices are out of a valid range * for \this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". + * \endif */ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) { @@ -8049,7 +8095,9 @@ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, * non-empty range of increasing indices or indices are out of a valid range * for \this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". + * \endif */ void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) { @@ -9564,12 +9612,35 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vectoralloc((int)r.size(),1); std::copy(r.begin(),r.end(),ret->getPointer()); return ret; } +/*! + * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). + * This method is not available into python because no available optimized data structure available to map std::vector< std::vector >. + * + * \param [in] v the input data structure to be translate into skyline format. + * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array. + * \param [out] dataIndex the second element of the skyline format. + */ +void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector >& v, DataArrayInt *& data, DataArrayInt *& dataIndex) +{ + int sz((int)v.size()); + MEDCouplingAutoRefCountObjectPtr ret0(DataArrayInt::New()),ret1(DataArrayInt::New()); + ret1->alloc(sz+1,1); + int *pt(ret1->getPointer()); *pt=0; + for(int i=0;ialloc(ret1->back(),1); + pt=ret0->getPointer(); + for(int i=0;i& groups, int newNb, std::vector< std::vector >& fidsOfGroups); MEDCOUPLING_EXPORT static DataArrayInt *BuildUnion(const std::vector& arr); MEDCOUPLING_EXPORT static DataArrayInt *BuildIntersection(const std::vector& arr); + MEDCOUPLING_EXPORT static void PutIntoToSkylineFrmt(const std::vector< std::vector >& v, DataArrayInt *& data, DataArrayInt *& dataIndex); MEDCOUPLING_EXPORT DataArrayInt *buildComplement(int nbOfElement) const; MEDCOUPLING_EXPORT DataArrayInt *buildSubstraction(const DataArrayInt *other) const; MEDCOUPLING_EXPORT DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const; diff --git a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx index bd7cc6973..beed83fce 100644 --- a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx +++ b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx @@ -734,7 +734,9 @@ DataArrayChar *DataArrayChar::changeNbOfComponents(int newNbOfComp, char dftValu * \throw If a component index (\a i) is not valid: * \a i < 0 || \a i >= \a this->getNumberOfComponents(). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". + * \endif */ DataArray *DataArrayChar::keepSelectedComponents(const std::vector& compoIds) const { @@ -763,9 +765,11 @@ DataArray *DataArrayChar::keepSelectedComponents(const std::vector& compoId * \throw If \a this is not allocated. * \throw If \a this and \a other arrays have different number of tuples. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example". * * \ref py_mcdataarrayint_meldwith "Here is a Python example". + * \endif */ void DataArrayChar::meldWith(const DataArrayChar *other) { @@ -826,7 +830,9 @@ void DataArrayChar::meldWith(const DataArrayChar *other) * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". + * \endif */ void DataArrayChar::setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) { @@ -889,7 +895,9 @@ void DataArrayChar::setPartOfValues1(const DataArrayChar *a, int bgTuples, int e * non-empty range of increasing indices or indices are out of a valid range * for \this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example". + * \endif */ void DataArrayChar::setPartOfValuesSimple1(char a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) { @@ -944,7 +952,9 @@ void DataArrayChar::setPartOfValuesSimple1(char a, int bgTuples, int endTuples, * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or * a->getNumberOfComponents() != (endComp - bgComp). * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". + * \endif */ void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) { @@ -1015,7 +1025,9 @@ void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples * \throw If any index of tuple/component given by bgTuples / bgComp is * out of a valid range for \a this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". + * \endif */ void DataArrayChar::setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) { @@ -1075,7 +1087,9 @@ void DataArrayChar::setPartOfValuesSimple2(char a, const int *bgTuples, const in * non-empty range of increasing indices or indices are out of a valid range * for \this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". + * \endif */ void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) { @@ -1147,7 +1161,9 @@ void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples * non-empty range of increasing indices or indices are out of a valid range * for \this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". + * \endif */ void DataArrayChar::setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) { diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index 181288b4b..eddba8553 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -371,8 +371,10 @@ void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) * \throw If the nodal connectivity of cells is not defined. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcmesh_fillFromAnalytic "Here is a C++ example".
* \ref py_mcmesh_fillFromAnalytic "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const { @@ -421,8 +423,10 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbO * \throw If the nodal connectivity of cells is not defined. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcmesh_fillFromAnalytic2 "Here is a C++ example".
* \ref py_mcmesh_fillFromAnalytic2 "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const { @@ -472,8 +476,10 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nb * \throw If the nodal connectivity of cells is not defined. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcmesh_fillFromAnalytic3 "Here is a C++ example".
* \ref py_mcmesh_fillFromAnalytic3 "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const std::string& func) const { @@ -626,8 +632,10 @@ const char *MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCel * \param [in,out] elts - vector returning ids of the found cells. It is cleared * before inserting ids. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".
* \ref py_mcumesh_getCellsContainingPoint "Here is a Python example". + * \endif */ void MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const { @@ -655,8 +663,10 @@ void MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std * Number of cells in contact with the *i*-th point is * \a eltsIndex[ *i*+1 ] - \a eltsIndex[ *i* ]. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".
* \ref py_mcumesh_getCellsContainingPoints "Here is a Python example". + * \endif */ void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const { diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index 5e9033058..1de136d5a 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -223,8 +223,10 @@ bool MEDCouplingPointSet::areCoordsEqualWithoutConsideringStr(const MEDCouplingP * \throw If the coordinates array is not set. * \throw If \a nodeId is not a valid index for the coordinates array. * + * \if ENABLE_EXAMPLES * \ref cpp_mcpointset_getcoordinatesofnode "Here is a C++ example".
* \ref py_mcpointset_getcoordinatesofnode "Here is a Python example". + * \endif */ void MEDCouplingPointSet::getCoordinatesOfNode(int nodeId, std::vector& coo) const { @@ -293,8 +295,10 @@ DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(double precision, * is to delete this array using decrRef() as it is no more needed. * \throw If the coordinates array is not set. * + * \if ENABLE_EXAMPLES * \ref cpp_mcpointset_findcommonnodes "Here is a C++ example".
* \ref py_mcpointset_findcommonnodes "Here is a Python example". + * \endif */ void MEDCouplingPointSet::findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const { @@ -315,8 +319,10 @@ void MEDCouplingPointSet::findCommonNodes(double prec, int limitNodeId, DataArra * array using decrRef() as it is no more needed. * \throw If the coordinates array is not set. * + * \if ENABLE_EXAMPLES * \ref cpp_mcpointset_getnodeidsnearpoint "Here is a C++ example".
* \ref py_mcpointset_getnodeidsnearpoint "Here is a Python example". + * \endif */ DataArrayInt *MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const { @@ -348,8 +354,10 @@ DataArrayInt *MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double * The caller is to delete this array using decrRef() as it is no more needed. * \throw If the coordinates array is not set. * + * \if ENABLE_EXAMPLES * \ref cpp_mcpointset_getnodeidsnearpoints "Here is a C++ example".
* \ref py_mcpointset_getnodeidsnearpoints "Here is a Python example". + * \endif */ void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfPoints, double eps, DataArrayInt *& c, DataArrayInt *& cI) const { @@ -386,8 +394,10 @@ DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
* \ref py_mcumesh_renumberNodes "Here is a Python example". + * \endif */ void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNodes) { @@ -412,8 +422,10 @@ void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNo * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
* \ref py_mcumesh_renumberNodes "Here is a Python example". + * \endif */ void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes) { @@ -449,8 +461,10 @@ void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfN * pre-allocated by the caller. * \throw If the coordinates array is not set. * + * \if ENABLE_EXAMPLES * \ref cpp_mcpointset_getBoundingBox "Here is a C++ example".
* \ref py_mcpointset_getBoundingBox "Here is a Python example". + * \endif */ void MEDCouplingPointSet::getBoundingBox(double *bbox) const { @@ -521,8 +535,10 @@ void MEDCouplingPointSet::recenterForMaxPrecision(double eps) * \throw If \a vector == NULL && \a this->getSpaceDimension() == 3. * \throw If Magnitude of \a vector is zero. * + * \if ENABLE_EXAMPLES * \ref cpp_mcpointset_rotate "Here is a C++ example".
* \ref py_mcpointset_rotate "Here is a Python example". + * \endif */ void MEDCouplingPointSet::rotate(const double *center, const double *vector, double angle) { @@ -544,8 +560,10 @@ void MEDCouplingPointSet::rotate(const double *center, const double *vector, dou * \throw If the coordinates array is not set. * \throw If \a vector == NULL. * + * \if ENABLE_EXAMPLES * \ref cpp_mcpointset_translate "Here is a C++ example".
* \ref py_mcpointset_translate "Here is a Python example". + * \endif */ void MEDCouplingPointSet::translate(const double *vector) { @@ -572,8 +590,10 @@ void MEDCouplingPointSet::translate(const double *vector) * \throw If the coordinates array is not set. * \throw If \a point == NULL. * + * \if ENABLE_EXAMPLES * \ref cpp_mcpointset_scale "Here is a C++ example".
* \ref py_mcpointset_scale "Here is a Python example". + * \endif */ void MEDCouplingPointSet::scale(const double *point, double factor) { @@ -1202,7 +1222,7 @@ void MEDCouplingPointSet::project2DCellOnXY(const int *startConn, const int *end { std::vector cpy(res); int nbNodes=(int)std::distance(startConn,endConn); - INTERP_KERNEL::PlanarIntersector::projection(&res[0],&cpy[0],nbNodes,nbNodes,1.e-12,0.,0.,true); + INTERP_KERNEL::PlanarIntersector::Projection(&res[0],&cpy[0],nbNodes,nbNodes,1.e-12,0./*max distance*/,-1./*min dot*/,0.,true); res.resize(2*nbNodes); for(int i=0;i * \ref py_mcumesh_buildPartOfMySelfNode "Here is a Python example". + * \endif */ MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const { @@ -1383,8 +1405,10 @@ MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelfNode(const int *begin * \throw If the nodal connectivity of cells is not defined. * \throw If the nodal connectivity includes an invalid id. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_zipConnectivityTraducer "Here is a C++ example".
* \ref py_mcumesh_zipConnectivityTraducer "Here is a Python example". + * \endif */ DataArrayInt *MEDCouplingPointSet::zipConnectivityTraducer(int compType, int startCellId) { @@ -1417,8 +1441,10 @@ DataArrayInt *MEDCouplingPointSet::zipConnectivityTraducer(int compType, int sta * to delete this array using decrRef() as it is no more needed. * \throw If the two meshes do not match. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
* \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". + * \endif */ void MEDCouplingPointSet::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) @@ -1471,8 +1497,10 @@ void MEDCouplingPointSet::checkDeepEquivalWith(const MEDCouplingMesh *other, int * to delete this array using decrRef() as it is no more needed. * \throw If the two meshes do not match. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
* \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". + * \endif */ void MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) @@ -1530,8 +1558,10 @@ void MEDCouplingPointSet::checkFastEquivalWith(const MEDCouplingMesh *other, dou * * \sa MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getCellIdsLyingOnNodes "Here is a C++ example".
* \ref py_mcumesh_getCellIdsLyingOnNodes "Here is a Python example". + * \endif */ DataArrayInt *MEDCouplingPointSet::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const { @@ -1556,8 +1586,10 @@ DataArrayInt *MEDCouplingPointSet::getCellIdsLyingOnNodes(const int *begin, cons * * \sa MEDCouplingPointSet::getCellIdsLyingOnNodes * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a C++ example".
* \ref py_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a Python example". + * \endif */ DataArrayInt *MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const { @@ -1575,8 +1607,10 @@ DataArrayInt *MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds(const int *p * \throw If the nodal connectivity of cells is not defined. * \throw If the nodal connectivity includes an invalid id. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".
* \ref py_mcumesh_zipCoordsTraducer "Here is a Python example". + * \endif */ DataArrayInt *MEDCouplingPointSet::zipCoordsTraducer() { @@ -1599,8 +1633,10 @@ DataArrayInt *MEDCouplingPointSet::zipCoordsTraducer() * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
* \ref py_mcumesh_mergeNodes "Here is a Python example". + * \endif */ DataArrayInt *MEDCouplingPointSet::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) { @@ -1624,8 +1660,10 @@ DataArrayInt *MEDCouplingPointSet::mergeNodes(double precision, bool& areNodesMe * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
* \ref py_mcumesh_mergeNodes "Here is a Python example". + * \endif */ DataArrayInt *MEDCouplingPointSet::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) { diff --git a/src/MEDCoupling/MEDCouplingRemapper.cxx b/src/MEDCoupling/MEDCouplingRemapper.cxx index 1c5e17a91..2602a556d 100644 --- a/src/MEDCoupling/MEDCouplingRemapper.cxx +++ b/src/MEDCoupling/MEDCouplingRemapper.cxx @@ -304,7 +304,7 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyUU() const MEDCouplingPointSet *src_mesh=static_cast(_src_ft->getMesh()); const MEDCouplingPointSet *target_mesh=static_cast(_target_ft->getMesh()); std::string srcMeth,trgMeth; - std::string method=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); + std::string method(checkAndGiveInterpolationMethodStr(srcMeth,trgMeth)); const int srcMeshDim=src_mesh->getMeshDimension(); int srcSpaceDim=-1; if(srcMeshDim!=-1) @@ -369,7 +369,8 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyUU() MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); } @@ -388,7 +389,8 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyUU() MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D1D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); @@ -412,7 +414,8 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyUU() MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); } @@ -459,7 +462,8 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyUU() MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D2D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); @@ -869,7 +873,12 @@ std::string MEDCouplingRemapper::checkAndGiveInterpolationMethodStr(std::string& throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkAndGiveInterpolationMethodStr : it appears that no all field templates have their mesh set !"); srcMeth=_src_ft->getDiscretization()->getRepr(); trgMeth=_target_ft->getDiscretization()->getRepr(); - std::string method(srcMeth); method+=trgMeth; + return BuildMethodFrom(srcMeth,trgMeth); +} + +std::string MEDCouplingRemapper::BuildMethodFrom(const std::string& meth1, const std::string& meth2) +{ + std::string method(meth1); method+=meth2; return method; } diff --git a/src/MEDCoupling/MEDCouplingRemapper.hxx b/src/MEDCoupling/MEDCouplingRemapper.hxx index 2904d5d9a..e6c38322a 100644 --- a/src/MEDCoupling/MEDCouplingRemapper.hxx +++ b/src/MEDCoupling/MEDCouplingRemapper.hxx @@ -74,6 +74,7 @@ namespace ParaMEDMEM MEDCOUPLINGREMAPPER_EXPORT const std::vector >& getCrudeMatrix() const; MEDCOUPLINGREMAPPER_EXPORT int getNumberOfColsOfMatrix() const; MEDCOUPLINGREMAPPER_EXPORT static void PrintMatrix(const std::vector >& m); + MEDCOUPLINGREMAPPER_EXPORT static std::string BuildMethodFrom(const std::string& meth1, const std::string& meth2); private: int prepareInterpKernelOnly(); int prepareInterpKernelOnlyUU(); diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 29d78628e..10cbc6bf2 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -314,8 +314,10 @@ void MEDCouplingUMesh::setMeshDimension(int meshDim) * * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain. * + * \if ENABLE_EXAMPLES * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
* \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". + * \endif */ void MEDCouplingUMesh::allocateCells(int nbOfCells) { @@ -345,8 +347,10 @@ void MEDCouplingUMesh::allocateCells(int nbOfCells) * \param [in] size - number of nodes constituting this cell. * \param [in] nodalConnOfCell - the connectivity of the cell to add. * + * \if ENABLE_EXAMPLES * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
* \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". + * \endif */ void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell) { @@ -381,8 +385,10 @@ void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, in * Compacts data arrays to release unused memory. This method is to be called after * finishing cell insertion using \a this->insertNextCell(). * + * \if ENABLE_EXAMPLES * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
* \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". + * \endif */ void MEDCouplingUMesh::finishInsertingCells() { @@ -583,8 +589,10 @@ void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getReverseNodalConnectivity "Here is a C++ example".
* \ref py_mcumesh_getReverseNodalConnectivity "Here is a Python example". + * \endif */ void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const { @@ -715,8 +723,10 @@ private: * \throw If \a desc == NULL || \a descIndx == NULL || \a revDesc == NULL || \a * revDescIndx == NULL. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_buildDescendingConnectivity "Here is a C++ example".
* \ref py_mcumesh_buildDescendingConnectivity "Here is a Python example". + * \endif * \sa buildDescendingConnectivity2() */ MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const @@ -784,8 +794,10 @@ MEDCouplingUMesh *MEDCouplingUMesh::explode3DMeshTo1D(DataArrayInt *desc, DataAr * \throw If \a desc == NULL || \a descIndx == NULL || \a revDesc == NULL || \a * revDescIndx == NULL. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_buildDescendingConnectivity2 "Here is a C++ example".
* \ref py_mcumesh_buildDescendingConnectivity2 "Here is a Python example". + * \endif * \sa buildDescendingConnectivity() */ MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const @@ -1006,8 +1018,10 @@ struct MEDCouplingAccVisit * \throw If the nodal connectivity of cells is node defined. * \throw If dimension of \a this mesh is not either 2 or 3. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_convertToPolyTypes "Here is a C++ example".
* \ref py_mcumesh_convertToPolyTypes "Here is a Python example". + * \endif */ void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd) { @@ -1015,7 +1029,7 @@ void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const i int dim=getMeshDimension(); if(dim<2 || dim>3) throw INTERP_KERNEL::Exception("Invalid mesh dimension : must be 2 or 3 !"); - int nbOfCells=getNumberOfCells(); + int nbOfCells(getNumberOfCells()); if(dim==2) { const int *connIndex=_nodal_connec_index->getConstPointer(); @@ -1040,47 +1054,50 @@ void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const i } else { - int *connIndex=_nodal_connec_index->getPointer(); - int connIndexLgth=_nodal_connec_index->getNbOfElems(); - const int *connOld=_nodal_connec->getConstPointer(); - int connOldLgth=_nodal_connec->getNbOfElems(); - std::vector connNew(connOld,connOld+connOldLgth); + int *connIndex(_nodal_connec_index->getPointer()); + const int *connOld(_nodal_connec->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr connNew(DataArrayInt::New()),connNewI(DataArrayInt::New()); connNew->alloc(0,1); connNewI->alloc(1,1); connNewI->setIJ(0,0,0); + std::vector toBeDone(nbOfCells,false); for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++) { if(*iter>=0 && *iter(),delta)); - connNew.insert(connNew.begin()+posP1,tmp+lgthOld,tmp+newLgth); - std::copy(tmp,tmp+lgthOld,connNew.begin()+pos+1); + std::size_t newLgth(std::distance(tmp,work)-1);//-1 for last -1 + connNew->pushBackValsSilent(tmp,tmp+newLgth); + connNewI->pushBackSilent(connNewI->back()+(int)newLgth); delete [] tmp; } else { - std::ostringstream oss; oss << "MEDCouplingUMesh::convertToPolyTypes : On rank #" << std::distance(cellIdsToConvertBg,iter) << " value is " << *iter << " which is not"; - oss << " in range [0," << nbOfCells << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + connNew->pushBackValsSilent(connOld+pos,connOld+posP1); + connNewI->pushBackSilent(connNewI->back()+posP1-pos); } } - _nodal_connec->alloc((int)connNew.size(),1); - int *newConnPtr=_nodal_connec->getPointer(); - std::copy(connNew.begin(),connNew.end(),newConnPtr); + setConnectivity(connNew,connNewI,false);//false because computeTypes called just behind. } computeTypes(); } @@ -1126,8 +1143,10 @@ void MEDCouplingUMesh::convertAllToPoly() * \throw If \a this mesh contains polyhedrons with the valid connectivity. * \throw If \a this mesh contains polyhedrons with odd number of nodes. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".
* \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". + * \endif */ void MEDCouplingUMesh::convertExtrudedPolyhedra() { @@ -1385,8 +1404,10 @@ void MEDCouplingUMesh::computeNodeIdsAlg(std::vector& nodeIdsInUse) const * \throw If the nodal connectivity of cells is not defined. * \throw If the nodal connectivity includes an invalid id. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getNodeIdsInUse "Here is a C++ example".
* \ref py_mcumesh_getNodeIdsInUse "Here is a Python example". + * \endif * \sa computeNodeIdsAlg() */ DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const @@ -1509,8 +1530,10 @@ DataArrayInt *MEDCouplingUMesh::computeNbOfFacesPerCell() const * \throw If the nodal connectivity of cells is not defined. * \throw If the nodal connectivity includes an invalid id. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".
* \ref py_mcumesh_zipCoordsTraducer "Here is a Python example". + * \endif */ DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() { @@ -1830,8 +1853,10 @@ void MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const D * \return bool - \c true if all cells of \a other mesh are present in the \a this * mesh. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_areCellsIncludedIn "Here is a C++ example".
* \ref py_mcumesh_areCellsIncludedIn "Here is a Python example". + * \endif * \sa checkDeepEquivalOnSameNodesWith() * \sa checkGeoEquivalWith() */ @@ -1958,8 +1983,10 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, in * \throw If the nodal connectivity of cells is not defined. * \throw If any cell id in the array \a begin is not valid. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_buildPartOfMySelf "Here is a C++ example".
* \ref py_mcumesh_buildPartOfMySelf "Here is a Python example". + * \endif */ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const { @@ -2146,8 +2173,10 @@ void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int * \throw If the nodal connectivity of cells is not defined. * \throw If any node id in \a begin is not valid. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_buildFacePartOfMySelfNode "Here is a C++ example".
* \ref py_mcumesh_buildFacePartOfMySelfNode "Here is a Python example". + * \endif */ MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const { @@ -2169,8 +2198,10 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begi * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_buildBoundaryMesh "Here is a C++ example".
* \ref py_mcumesh_buildBoundaryMesh "Here is a Python example". + * \endif */ MEDCouplingPointSet *MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const { @@ -2321,8 +2352,10 @@ MEDCouplingUMesh *MEDCouplingUMesh::computeSkin() const * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is node defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_findBoundaryNodes "Here is a C++ example".
* \ref py_mcumesh_findBoundaryNodes "Here is a Python example". + * \endif */ DataArrayInt *MEDCouplingUMesh::findBoundaryNodes() const { @@ -2424,8 +2457,10 @@ void MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_renumberNodesInConn "Here is a C++ example".
* \ref py_mcumesh_renumberNodesInConn "Here is a Python example". + * \endif */ void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) { @@ -2580,8 +2615,10 @@ void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getCellsInBoundingBox "Here is a C++ example".
* \ref py_mcumesh_getCellsInBoundingBox "Here is a Python example". + * \endif */ DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const { @@ -3296,8 +3333,10 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to * delete this array using decrRef() as it is no more needed. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getPartMeasureField "Here is a C++ example".
* \ref py_mcumesh_getPartMeasureField "Here is a Python example". + * \endif * \sa getMeasureField() */ DataArrayDouble *MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *begin, const int *end) const @@ -3465,8 +3504,10 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const * \throw If the mesh and space dimension is not as specified above. * \sa buildOrthogonalField() * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_buildPartOrthogonalField "Here is a C++ example".
* \ref py_mcumesh_buildPartOrthogonalField "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *begin, const int *end) const { @@ -4057,8 +4098,10 @@ int MEDCouplingUMesh::getCellContainingPoint(const double *pos, double eps) cons * \throw If the coordinates array is not set. * \throw If \a this->getMeshDimension() != \a this->getSpaceDimension(). * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".
* \ref py_mcumesh_getCellsContainingPoint "Here is a Python example". + * \endif */ void MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const { @@ -4087,6 +4130,41 @@ namespace ParaMEDMEM INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; } // end }; + + /*! + * Warning the nodes in \a m should be decrRefed ! To avoid that Node * pointer be replaced by another instance. + */ + INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge2(INTERP_KERNEL::NormalizedCellType typ, const int *bg, const double *coords2D, std::map& m) + { + INTERP_KERNEL::Edge *ret=0; + INTERP_KERNEL::Node *n0(new INTERP_KERNEL::Node(coords2D[2*bg[0]],coords2D[2*bg[0]+1])),*n1(new INTERP_KERNEL::Node(coords2D[2*bg[1]],coords2D[2*bg[1]+1])); + m[n0]=bg[0]; m[n1]=bg[1]; + switch(typ) + { + case INTERP_KERNEL::NORM_SEG2: + { + ret=new INTERP_KERNEL::EdgeLin(n0,n1); + break; + } + case INTERP_KERNEL::NORM_SEG3: + { + INTERP_KERNEL::Node *n2(new INTERP_KERNEL::Node(coords2D[2*bg[2]],coords2D[2*bg[2]+1])); m[n2]=bg[2]; + INTERP_KERNEL::EdgeLin *e1(new INTERP_KERNEL::EdgeLin(n0,n2)),*e2(new INTERP_KERNEL::EdgeLin(n2,n1)); + INTERP_KERNEL::SegSegIntersector inters(*e1,*e2); + // is the SEG3 degenerated, and thus can be reduced to a SEG2? + bool colinearity(inters.areColinears()); + delete e1; delete e2; + if(colinearity) + { ret=new INTERP_KERNEL::EdgeLin(n0,n1); } + else + { ret=new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1); } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge2 : Expecting a mesh with spaceDim==2 and meshDim==1 !"); + } + return ret; + } INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge(INTERP_KERNEL::NormalizedCellType typ, std::map >& mapp2, const int *bg) { @@ -4283,8 +4361,10 @@ void MEDCouplingUMesh::getCellsContainingPointsAlg(const double *coords, const d * \throw If the coordinates array is not set. * \throw If \a this->getMeshDimension() != \a this->getSpaceDimension(). * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".
* \ref py_mcumesh_getCellsContainingPoints "Here is a Python example". + * \endif */ void MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const @@ -5708,8 +5788,10 @@ void MEDCouplingUMesh::convertDegeneratedCells() * \throw If \a this->getMeshDimension() != 2. * \throw If \a this->getSpaceDimension() != 3. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".
* \ref py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example". + * \endif */ void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector& cells) const { @@ -5742,8 +5824,10 @@ void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool po * \throw If \a this->getMeshDimension() != 2. * \throw If \a this->getSpaceDimension() != 3. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".
* \ref py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example". + * \endif */ void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly) { @@ -5796,8 +5880,10 @@ void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly) * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".
* \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". + * \endif */ void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector& cells) const { @@ -5827,8 +5913,10 @@ void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector& cell * \throw If the nodal connectivity of cells is not defined. * \throw If the reparation fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".
* \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". + * \endif * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells */ void MEDCouplingUMesh::orientCorrectlyPolyhedrons() @@ -5872,8 +5960,10 @@ void MEDCouplingUMesh::orientCorrectlyPolyhedrons() * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a C++ example".
* \ref py_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a Python example". + * \endif * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells */ DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells() @@ -6272,9 +6362,9 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree(double arcDetEps) const { int mDim(getMeshDimension()),sDim(getSpaceDimension()); - if(mDim!=2 || sDim!=2) + if((mDim==3 && sDim==3) || (mDim==2 && sDim==3) || (mDim==1 && sDim==1) || ( mDim==1 && sDim==3)) // Compute refined boundary box for quadratic elements only in 2D. return getBoundingBoxForBBTreeFast(); - else + if((mDim==2 && sDim==2) || (mDim==1 && sDim==2)) { bool presenceOfQuadratic(false); for(std::set::const_iterator it=_types.begin();it!=_types.end();it++) @@ -6283,11 +6373,14 @@ DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree(double arcDetEps) con if(cm.isQuadratic()) presenceOfQuadratic=true; } - if(presenceOfQuadratic) + if(!presenceOfQuadratic) + return getBoundingBoxForBBTreeFast(); + if(mDim==2 && sDim==2) return getBoundingBoxForBBTree2DQuadratic(arcDetEps); else - return getBoundingBoxForBBTreeFast(); + return getBoundingBoxForBBTree1DQuadratic(arcDetEps); } + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree : Managed dimensions are (mDim=1,sDim=1), (mDim=1,sDim=2), (mDim=1,sDim=3), (mDim=2,sDim=2), (mDim=2,sDim=3) and (mDim=3,sDim=3) !"); } /*! @@ -6339,20 +6432,23 @@ DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTreeFast() const } /*! - * This method aggregate the bbox regarding foreach 2D cell in \a this the whole shape. So this method is particulary useful for 2D meshes having quadratic cells - * because for this type of cells getBoundingBoxForBBTreeFast method may return invalid bounding boxes. + * This method aggregates the bbox of each 2D cell in \a this considering the whole shape. This method is particularly + * useful for 2D meshes having quadratic cells + * because for this type of cells getBoundingBoxForBBTreeFast method may return invalid bounding boxes (since it just considers + * the two extremities of the arc of circle). * * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. * \throw If \a this is not fully defined. * \throw If \a this is not a mesh with meshDimension equal to 2. * \throw If \a this is not a mesh with spaceDimension equal to 2. + * \sa MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic */ DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic(double arcDetEps) const { checkFullyDefined(); - int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); - if(mDim!=2 || spaceDim!=2) + int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells()); + if(spaceDim!=2 || mDim!=2) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic : This method should be applied on mesh with mesh dimension equal to 2 and space dimension also equal to 2!"); MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); double *bbox(ret->getPointer()); @@ -6362,7 +6458,7 @@ DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic(double arc { const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*connI])); int sz(connI[1]-connI[0]-1); - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1e-12; + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=arcDetEps; std::vector nodes(sz); INTERP_KERNEL::QuadraticPolygon *pol(0); for(int j=0;j ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); + double *bbox(ret->getPointer()); + const double *coords(_coords->getConstPointer()); + const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); + for(int i=0;i nodes(sz); + INTERP_KERNEL::Edge *edge(0); + for(int j=0;jgetBounds()); + bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); edge->decrRef(); + } + return ret.retn(); +} + /// @cond INTERNAL namespace ParaMEDMEMImpl @@ -7306,8 +7447,10 @@ DataArrayDouble *MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const * \throw If the coordinates array is not set. * \throw If the nodal connectivity of cells is not defined. * + * \if ENABLE_EXAMPLES * \ref cpp_mcumesh_getPartBarycenterAndOwner "Here is a C++ example".
* \ref py_mcumesh_getPartBarycenterAndOwner "Here is a Python example". + * \endif */ DataArrayDouble *MEDCouplingUMesh::getPartBarycenterAndOwner(const int *begin, const int *end) const { @@ -7863,17 +8006,43 @@ void MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, */ bool MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords) { + std::size_t i, ip1; double v[3]={0.,0.,0.}; std::size_t sz=std::distance(begin,end); if(isQuadratic) sz/=2; - for(std::size_t i=0;i0.; + double ret = vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2]; + + // Try using quadratic points if standard points are degenerated (for example a QPOLYG with two + // SEG3 forming a circle): + if (fabs(ret) < INTERP_KERNEL::DEFAULT_ABS_TOL && isQuadratic) + { + v[0] = 0.0; v[1] = 0.0; v[2] = 0.0; + for(std::size_t j=0;j0.); } /*! @@ -8172,34 +8341,20 @@ void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, c } } -/*! - * This method makes the assumption spacedimension == meshdimension == 2. - * This method works only for linear cells. - * - * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0) - */ -DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const { - if(getMeshDimension()!=2 || getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr m=computeSkin(); - MEDCouplingAutoRefCountObjectPtr o2n=m->zipCoordsTraducer(); - int nbOfNodesExpected=m->getNumberOfNodes(); - if(m->getNumberOfCells()!=nbOfNodesExpected) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part or a quadratic 2D mesh !"); - MEDCouplingAutoRefCountObjectPtr n2o=o2n->invertArrayO2N2N2O(m->getNumberOfNodes()); - const int *n2oPtr=n2o->getConstPointer(); + int nbOfNodesExpected(skin->getNumberOfNodes()); + const int *n2oPtr(n2o->getConstPointer()); MEDCouplingAutoRefCountObjectPtr revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New()); - m->getReverseNodalConnectivity(revNodal,revNodalI); - const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer(); - const int *nodalPtr=m->getNodalConnectivity()->getConstPointer(); - const int *nodalIPtr=m->getNodalConnectivityIndex()->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfNodesExpected+1,1); - int *work=ret->getPointer(); *work++=INTERP_KERNEL::NORM_POLYGON; + skin->getReverseNodalConnectivity(revNodal,revNodalI); + const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer()); + const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer()); + const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1); + int *work(ret->getPointer()); *work++=INTERP_KERNEL::NORM_POLYGON; if(nbOfNodesExpected<1) return ret.retn(); - int prevCell=0; - int prevNode=nodalPtr[nodalIPtr[0]+1]; + int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]); *work++=n2oPtr[prevNode]; for(int i=1;i shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]); shar.erase(prevCell); @@ -8219,17 +8374,89 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const prevNode=curNode; } else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected 2 !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 2 !"); } else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected 1 !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 1 !"); } else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected cell !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected cell !"); + } + return ret.retn(); +} + +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const +{ + int nbOfNodesExpected(skin->getNumberOfNodes()); + int nbOfTurn(nbOfNodesExpected/2); + const int *n2oPtr(n2o->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New()); + skin->getReverseNodalConnectivity(revNodal,revNodalI); + const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer()); + const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer()); + const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1); + int *work(ret->getPointer()); *work++=INTERP_KERNEL::NORM_QPOLYG; + if(nbOfNodesExpected<1) + return ret.retn(); + int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]); + *work=n2oPtr[prevNode]; work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[0]+3]]; work++; + for(int i=1;i conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3); + conn.erase(prevNode); + if(conn.size()==1) + { + int curNode(*(conn.begin())); + *work=n2oPtr[curNode]; + std::set shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]); + shar.erase(prevCell); + if(shar.size()==1) + { + int curCell(*(shar.begin())); + work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[curCell]+3]]; + prevCell=curCell; + prevNode=curNode; + work++; + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 2 !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 1 !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected cell !"); } return ret.retn(); } +/*! + * This method makes the assumption spacedimension == meshdimension == 2. + * This method works only for linear cells. + * + * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0) + */ +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const +{ + if(getMeshDimension()!=2 || getSpaceDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !"); + MEDCouplingAutoRefCountObjectPtr skin(computeSkin()); + int oldNbOfNodes(skin->getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr o2n(skin->zipCoordsTraducer()); + int nbOfNodesExpected(skin->getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr n2o(o2n->invertArrayO2N2N2O(oldNbOfNodes)); + int nbCells(skin->getNumberOfCells()); + if(nbCells==nbOfNodesExpected) + return buildUnionOf2DMeshLinear(skin,n2o); + else if(2*nbCells==nbOfNodesExpected) + return buildUnionOf2DMeshQuadratic(skin,n2o); + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part of a 2D mesh !"); +} + /*! * This method makes the assumption spacedimension == meshdimension == 3. * This method works only for linear cells. @@ -8560,6 +8787,208 @@ void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCo } } +void IKGeo2DInternalMapper2(INTERP_KERNEL::Node *n, const std::map& m, int forbVal0, int forbVal1, std::vector& isect) +{ + std::map::const_iterator it(m.find(n)); + if(it==m.end()) + throw INTERP_KERNEL::Exception("Internal error in remapping !"); + int v((*it).second); + if(v==forbVal0 || v==forbVal1) + return ; + if(std::find(isect.begin(),isect.end(),v)==isect.end()) + isect.push_back(v); +} + +bool IKGeo2DInternalMapper(const INTERP_KERNEL::ComposedEdge& c, const std::map& m, int forbVal0, int forbVal1, std::vector& isect) +{ + int sz(c.size()); + if(sz<=1) + return false; + bool presenceOfOn(false); + for(int i=0;igetLoc()!=INTERP_KERNEL::FULL_ON_1) + continue ; + IKGeo2DInternalMapper2(e->getStartNode(),m,forbVal0,forbVal1,isect); + IKGeo2DInternalMapper2(e->getEndNode(),m,forbVal0,forbVal1,isect); + } + return presenceOfOn; +} + +/** + * This method split some of edges of 2D cells in \a this. The edges to be split are specified in \a subNodesInSeg and in \a subNodesInSegI using index storage mode. + * To do the work this method can optionnaly needs information about middle of subedges for quadratic cases if a minimal creation of new nodes is wanted. + * So this method try to reduce at most the number of new nodes. The only case that can lead this method to add nodes if a SEG3 is split without information of middle. + * \b WARNING : is returned value is different from 0 a call to MEDCouplingUMesh::mergeNodes is necessary to avoid to have a non conform mesh. + * + * \return int - the number of new nodes created (in most of cases 0). + * + * \throw If \a this is not coherent. + * \throw If \a this has not spaceDim equal to 2. + * \throw If \a this has not meshDim equal to 2. + * \throw If some subcells needed to be split are orphan. + * \sa MEDCouplingUMesh::conformize2D + */ +int MEDCouplingUMesh::split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt, const DataArrayInt *midOptI) +{ + if(!desc || !descI || !subNodesInSeg || !subNodesInSegI) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : the 4 first arrays must be not null !"); + desc->checkAllocated(); descI->checkAllocated(); subNodesInSeg->checkAllocated(); subNodesInSegI->checkAllocated(); + if(getSpaceDimension()!=2 || getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : This method only works for meshes with spaceDim=2 and meshDim=2 !"); + if(midOpt==0 && midOptI==0) + { + split2DCellsLinear(desc,descI,subNodesInSeg,subNodesInSegI); + return 0; + } + else if(midOpt!=0 && midOptI!=0) + return split2DCellsQuadratic(desc,descI,subNodesInSeg,subNodesInSegI,midOpt,midOptI); + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : middle parameters must be set to null for all or not null for all."); +} + +/*! + * \b WARNING this method is \b potentially \b non \b const (if returned array is empty). + * \b WARNING this method lead to have a non geometric type sorted mesh (for MED file users) ! + * This method performs a conformization of \b this. So if a edge in \a this can be split into entire edges in \a this this method + * will suppress such edges to use sub edges in \a this. So this method does not add nodes in \a this if merged edges have same nature each other (Linear,Quadratic). + * Whatever the returned value, this method does not alter the order of cells in \a this neither the orientation of cells. + * The modified cells if any are systematically declared as NORM_POLYGON or NORM_QPOLYG depending on the + * + * This method expects that \b this has a meshDim equal 2 and spaceDim equal to 2 too. + * This method expects that all nodes in \a this are not closer than \a eps. + * If it is not the case you can invoke MEDCouplingUMesh::mergeNodes before calling this method. + * + * \param [in] eps the relative error to detect merged edges. + * \return DataArrayInt * - The list of cellIds in \a this that have been subdivided. If empty, nothing changed in \a this (as if it were a const method). The array is a newly allocated array + * that the user is expected to deal with. + * + * \throw If \a this is not coherent. + * \throw If \a this has not spaceDim equal to 2. + * \throw If \a this has not meshDim equal to 2. + * \sa MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::split2DCells + */ +DataArrayInt *MEDCouplingUMesh::conformize2D(double eps) +{ + static const int SPACEDIM=2; + checkCoherency(); + if(getSpaceDimension()!=2 || getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !"); + MEDCouplingAutoRefCountObjectPtr desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr mDesc(buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1)); + const int *c(mDesc->getNodalConnectivity()->getConstPointer()),*ci(mDesc->getNodalConnectivityIndex()->getConstPointer()),*rd(revDesc1->getConstPointer()),*rdi(revDescIndx1->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr bboxArr(mDesc->getBoundingBoxForBBTree()); + const double *bbox(bboxArr->begin()),*coords(getCoords()->begin()); + int nCell(getNumberOfCells()),nDescCell(mDesc->getNumberOfCells()); + std::vector< std::vector > intersectEdge(nDescCell),overlapEdge(nDescCell); + std::vector addCoo; + BBTree myTree(bbox,0,0,nDescCell,-eps); + INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; + for(int i=0;i candidates; + myTree.getIntersectingElems(bbox+i*2*SPACEDIM,candidates); + for(std::vector::const_iterator it=candidates.begin();it!=candidates.end();it++) + if(*it>i) + { + std::map m; + INTERP_KERNEL::Edge *e1(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)), + *e2(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[*it]],c+ci[*it]+1,coords,m)); + INTERP_KERNEL::MergePoints merge; + INTERP_KERNEL::QuadraticPolygon c1,c2; + e1->intersectWith(e2,merge,c1,c2); + e1->decrRef(); e2->decrRef(); + if(IKGeo2DInternalMapper(c1,m,c[ci[i]+1],c[ci[i]+2],intersectEdge[i])) + overlapEdge[i].push_back(*it); + if(IKGeo2DInternalMapper(c2,m,c[ci[*it]+1],c[ci[*it]+2],intersectEdge[*it])) + overlapEdge[*it].push_back(i); + for(std::map::const_iterator it2=m.begin();it2!=m.end();it2++) + (*it2).first->decrRef(); + } + } + // splitting done. sort intersect point in intersectEdge. + std::vector< std::vector > middle(nDescCell); + int nbOf2DCellsToBeSplit(0); + bool middleNeedsToBeUsed(false); + std::vector cells2DToTreat(nDescCell,false); + for(int i=0;i& isect(intersectEdge[i]); + int sz((int)isect.size()); + if(sz>1) + { + std::map m; + INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)); + e->sortSubNodesAbs(coords,isect); + e->decrRef(); + for(std::map::const_iterator it2=m.begin();it2!=m.end();it2++) + (*it2).first->decrRef(); + } + if(sz!=0) + { + int idx0(rdi[i]),idx1(rdi[i+1]); + if(idx1-idx0!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : internal error #0 !"); + if(!cells2DToTreat[rd[idx0]]) + { + cells2DToTreat[rd[idx0]]=true; + nbOf2DCellsToBeSplit++; + } + // try to reuse at most eventual 'middle' of SEG3 + std::vector& mid(middle[i]); + mid.resize(sz+1,-1); + if((INTERP_KERNEL::NormalizedCellType)c[ci[i]]==INTERP_KERNEL::NORM_SEG3) + { + middleNeedsToBeUsed=true; + const std::vector& candidates(overlapEdge[i]); + std::vector trueCandidates; + for(std::vector::const_iterator itc=candidates.begin();itc!=candidates.end();itc++) + if((INTERP_KERNEL::NormalizedCellType)c[ci[*itc]]==INTERP_KERNEL::NORM_SEG3) + trueCandidates.push_back(*itc); + int stNode(c[ci[i]+1]),endNode(isect[0]); + for(int j=0;j::const_iterator itc=trueCandidates.begin();itc!=trueCandidates.end();itc++) + { + int tmpSt(c[ci[*itc]+1]),tmpEnd(c[ci[*itc]+2]); + if((tmpSt==stNode && tmpEnd==endNode) || (tmpSt==endNode && tmpEnd==stNode)) + { mid[j]=*itc; break; } + } + stNode=endNode; + endNode=j ret(DataArrayInt::New()),notRet(DataArrayInt::New()); ret->alloc(nbOf2DCellsToBeSplit,1); + if(nbOf2DCellsToBeSplit==0) + return ret.retn(); + // + int *retPtr(ret->getPointer()); + for(int i=0;i mSafe,nSafe,oSafe,pSafe,qSafe,rSafe; + DataArrayInt *m(0),*n(0),*o(0),*p(0),*q(0),*r(0); + MEDCouplingUMesh::ExtractFromIndexedArrays(ret->begin(),ret->end(),desc1,descIndx1,m,n); mSafe=m; nSafe=n; + DataArrayInt::PutIntoToSkylineFrmt(intersectEdge,o,p); oSafe=o; pSafe=p; + if(middleNeedsToBeUsed) + { DataArrayInt::PutIntoToSkylineFrmt(middle,q,r); qSafe=q; rSafe=r; } + MEDCouplingAutoRefCountObjectPtr modif(static_cast(buildPartOfMySelf(ret->begin(),ret->end(),true))); + int nbOfNodesCreated(modif->split2DCells(mSafe,nSafe,oSafe,pSafe,qSafe,rSafe)); + setCoords(modif->getCoords());//if nbOfNodesCreated==0 modif and this have the same coordinates pointer so this line has no effect. But for quadratic cases this line is important. + setPartOfMySelf(ret->begin(),ret->end(),*modif); + { + bool areNodesMerged; int newNbOfNodes; + if(nbOfNodesCreated!=0) + MEDCouplingAutoRefCountObjectPtr tmp(mergeNodes(eps,areNodesMerged,newNbOfNodes)); + } + return ret.retn(); +} + /*! * This method is private and is the first step of Partition of 2D mesh (spaceDim==2 and meshDim==2). * It builds the descending connectivity of the two meshes, and then using a binary tree @@ -9633,6 +10062,116 @@ MEDCoupling1SGTUMesh *MEDCouplingUMesh::tetrahedrize(int policy, DataArrayInt *& return ret0.retn(); } +/*! + * It is the linear part of MEDCouplingUMesh::split2DCells. Here no additionnal nodes will be added in \b this. So coordinates pointer remain unchanged (is not even touch). + * + * \sa MEDCouplingUMesh::split2DCells + */ +void MEDCouplingUMesh::split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI) +{ + checkConnectivityFullyDefined(); + int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+subNodesInSeg->getNumberOfTuples()); + MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach); + const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin()); + int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer()); + int prevPosOfCi(ciPtr[0]); + for(int i=0;iend()!=cPtr) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsLinear : Some of edges to be split are orphan !"); + _nodal_connec->decrRef(); + _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_POLYGON); +} + +int internalAddPoint(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter) +{ + if(id!=-1) + return id; + else + { + int ret(nodesCnter++); + double newPt[2]; + e->getMiddleOfPoints(coo+2*startId,coo+2*endId,newPt); + addCoo.insertAtTheEnd(newPt,newPt+2); + return ret; + } +} + +/*! + * It is the quadratic part of MEDCouplingUMesh::split2DCells. Here some additionnal nodes can be added at the end of coordinates array object. + * + * \return int - the number of new nodes created. + * \sa MEDCouplingUMesh::split2DCells + */ +int MEDCouplingUMesh::split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI) +{ + checkCoherency(); + int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+2*subNodesInSeg->getNumberOfTuples()),nodesCnt(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach); + MEDCouplingAutoRefCountObjectPtr addCoo(DataArrayDouble::New()); addCoo->alloc(0,1); + const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin()); + const int *midPtr(mid->begin()),*midIPtr(midI->begin()); + const double *oldCoordsPtr(getCoords()->begin()); + int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer()); + int prevPosOfCi(ciPtr[0]); + for(int i=0;i ns(3); + ns[0]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]+1]); + ns[1]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]+1]); + ns[2]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]+1]); + MEDCouplingAutoRefCountObjectPtr e(INTERP_KERNEL::QuadraticPolygon::BuildArcCircleEdge(ns)); + for(int k=0;kend()!=cPtr) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsQuadratic : Some of edges to be split are orphan !"); + _nodal_connec->decrRef(); + _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_QPOLYG); + addCoo->rearrange(2); + MEDCouplingAutoRefCountObjectPtr coo(DataArrayDouble::Aggregate(getCoords(),addCoo));//info are copied from getCoords() by using Aggregate + setCoords(coo); + return addCoo->getNumberOfTuples(); +} + MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)), _own_cell(true),_cell_id(-1),_nb_cell(0) { diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index eaacda684..65852e9ec 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -167,6 +167,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTreeFast() const; MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const; + MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy); MEDCOUPLING_EXPORT bool isFullyQuadratic() const; MEDCOUPLING_EXPORT bool isPresenceOfQuadratic() const; @@ -218,6 +219,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; MEDCOUPLING_EXPORT DataArrayDouble *getPartBarycenterAndOwner(const int *begin, const int *end) const; MEDCOUPLING_EXPORT DataArrayDouble *computePlaneEquationOf3DFaces() const; + MEDCOUPLING_EXPORT DataArrayInt *conformize2D(double eps); + MEDCOUPLING_EXPORT int split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt=0, const DataArrayInt *midOptI=0); MEDCOUPLING_EXPORT static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da); MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(std::vector& a); @@ -287,6 +290,8 @@ namespace ParaMEDMEM DataArrayInt *convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; DataArrayInt *convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; DataArrayInt *convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; + DataArrayInt *buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const; + DataArrayInt *buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const; template void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const; @@ -316,6 +321,8 @@ namespace ParaMEDMEM const int *desc, const int *descIndx, std::vector< std::pair >& cut3DSurf) throw(INTERP_KERNEL::Exception); void assemblyForSplitFrom3DSurf(const std::vector< std::pair >& cut3DSurf, const int *desc, const int *descIndx, DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const throw(INTERP_KERNEL::Exception); + void split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI); + int split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI); public: MEDCOUPLING_EXPORT static DataArrayInt *ComputeRangesFromTypeDistribution(const std::vector& code); MEDCOUPLING_EXPORT static const int N_MEDMEM_ORDER=24; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx index 79b232f4a..365cea85a 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx @@ -261,6 +261,38 @@ void MEDCouplingBasicsTest2::testCellOrientation2() m2->decrRef(); } +void MEDCouplingBasicsTest2::testCellOrientation3() +{ + MEDCouplingUMesh *m = MEDCouplingUMesh::New("circle", 2); + + double coords[8]={ 0.,0., 0.,0., 0.,0., 0.,0.}; + coords[0] = cos(-M_PI/4.0); coords[1] = sin(-M_PI/4.0); + coords[2] = cos(3*M_PI/4.0); coords[3] = sin(3*M_PI/4.0); + coords[4] = cos(5*M_PI/4.0); coords[5] = sin(5*M_PI/4.0); + coords[6] = cos(M_PI/4.0); coords[7] = sin(M_PI/4.0); + + int conn[4]= { 0,1,2,3 }; + double vec[3]={0.,0.,-1.}; + m->allocateCells(1); + m->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,4,conn); + m->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + std::copy(coords,coords+8,myCoords->getPointer()); + m->setCoords(myCoords); + myCoords->decrRef(); + m->changeSpaceDimension(3); + + std::vector res1; + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT(res1.empty()); + vec[2] = 1.0; + res1.clear(); + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT_EQUAL(1,(int)res1.size()); + m->decrRef(); +} + /*! * This test check polyhedron true barycenter computation. */ diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx index 2ca46e688..5247e3c6b 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx @@ -40,6 +40,7 @@ namespace ParaMEDMEM CPPUNIT_TEST( testGaussPointNEField1 ); CPPUNIT_TEST( testCellOrientation1 ); CPPUNIT_TEST( testCellOrientation2 ); + CPPUNIT_TEST( testCellOrientation3 ); CPPUNIT_TEST( testPolyhedronBarycenter ); CPPUNIT_TEST( testNormL12Integ1D ); CPPUNIT_TEST( testAreaBary2D ); @@ -83,6 +84,7 @@ namespace ParaMEDMEM void testGaussPointNEField1(); void testCellOrientation1(); void testCellOrientation2(); + void testCellOrientation3(); void testPolyhedronBarycenter(); void testNormL12Integ1D(); void testAreaBary2D(); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx index fb039d015..34846350c 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx @@ -1798,6 +1798,64 @@ void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp6() d2->decrRef(); } +void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp7() +{ + double eps = 1.0e-8; + // coordinates circle - SEE getCircle() on the Python side + DataArrayDouble *coords1=DataArrayDouble::New(); + const double coordsData1[16]={0.5328427124746189, -0.08284271247461905, -0.03284271247461901, 0.4828427124746191, -0.03284271247461906, -0.082842712474619, 0.5328427124746191, 0.482842712474619}; + coords1->useArray(coordsData1,false,CPP_DEALLOC,8,2); + // connectivity + DataArrayInt *conn1=DataArrayInt::New(); + const int connData1[5]={INTERP_KERNEL::NORM_QPOLYG,0,1,2,3}; + conn1->useArray(connData1,false,CPP_DEALLOC,5,1); + DataArrayInt *connI1=DataArrayInt::New(); + const int connIData1[2]={0,5}; + connI1->useArray(connIData1,false,CPP_DEALLOC,2,1); + MEDCouplingUMesh *m1=MEDCouplingUMesh::New("circle",2); + m1->setCoords(coords1); + m1->setConnectivity(conn1,connI1,true); + coords1->decrRef(); conn1->decrRef(); connI1->decrRef(); + + // square + DataArrayDouble *coords2=DataArrayDouble::New(); + const double coordsData2[8]={-0.5,-0.5, -0.5, 0.5, 0.5, 0.5, 0.5,-0.5}; + coords2->useArray(coordsData2,false,CPP_DEALLOC,4,2); + // connectivity + DataArrayInt *conn2=DataArrayInt::New(); + const int connData2[5]={INTERP_KERNEL::NORM_POLYGON, 0,1,2,3}; + conn2->useArray(connData2,false,CPP_DEALLOC,5,1); + DataArrayInt *connI2=DataArrayInt::New(); + const int connIData2[2]={0,5}; + connI2->useArray(connIData2,false,CPP_DEALLOC,2,1); + MEDCouplingUMesh *m2=MEDCouplingUMesh::New("square",2); + m2->setCoords(coords2); + m2->setConnectivity(conn2,connI2,true); + coords2->decrRef(); conn2->decrRef(); connI2->decrRef(); + + DataArrayInt * resToM1 = 0, * resToM2 = 0; + MEDCouplingUMesh *m_intersec=MEDCouplingUMesh::Intersect2DMeshes(m2, m1, eps, resToM1, resToM2); + m_intersec->zipCoords(); + + const double coo_tgt[34]={-0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.03284271247461901, 0.4828427124746191, \ + -0.014575131106459124, 0.5000000000000001, 0.5, -0.11224989991991996, 0.24271243444677046, 0.5, 0.5, 0.19387505004004, \ + -0.04799910280454185, -0.06682678787499614, -0.023843325638122054, 0.4915644577163915, 0.5, -0.30612494995996, 0.0, -0.5,\ + -0.5, 0.0, -0.25728756555322957, 0.5, -0.023843325638122026, 0.49156445771639157, -0.04799910280454181, -0.06682678787499613}; + const int conn_tgt[22]={32, 5, 2, 6, 4, 7, 8, 9, 10, 32, 6, 3, 0, 1, 5, 4, 11, 12, 13, 14, 15, 16}; + const int connI_tgt[3]={0, 9, 22}; + const int res1_tgt[2] = {0, 0}; + const int res2_tgt[2] = {0, -1}; + + CPPUNIT_ASSERT(std::equal(conn_tgt,conn_tgt+22,m_intersec->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(connI_tgt,connI_tgt+3,m_intersec->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(res1_tgt,res1_tgt+2,resToM1->getConstPointer())); + CPPUNIT_ASSERT(std::equal(res2_tgt,res2_tgt+2,resToM2->getConstPointer())); + for(int i=0;i<34;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(coo_tgt[i],m_intersec->getCoords()->getIJ(0,i),1e-12); + m1->decrRef(); m2->decrRef(); m_intersec->decrRef(); + resToM1->decrRef(); resToM2->decrRef(); +} + void MEDCouplingBasicsTest5::testDAIBuildSubstractionOptimized1() { const int tab1[7]={1,3,5,6,7,9,13}; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx index 9df6e65fb..4b1770100 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx @@ -72,6 +72,7 @@ namespace ParaMEDMEM CPPUNIT_TEST( testDAIPartitionByDifferentValues1 ); CPPUNIT_TEST( testDAICheckMonotonic1 ); CPPUNIT_TEST( testIntersect2DMeshesTmp6 ); + CPPUNIT_TEST( testIntersect2DMeshesTmp7 ); CPPUNIT_TEST( testDAIBuildSubstractionOptimized1 ); CPPUNIT_TEST( testDAIIsStrictlyMonotonic1 ); CPPUNIT_TEST( testSimplexize3 ); @@ -113,6 +114,7 @@ namespace ParaMEDMEM void testDAIPartitionByDifferentValues1(); void testDAICheckMonotonic1(); void testIntersect2DMeshesTmp6(); + void testIntersect2DMeshesTmp7(); void testDAIBuildSubstractionOptimized1(); void testDAIIsStrictlyMonotonic1(); void testSimplexize3(); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 734391fa9..c79c57ff1 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -2183,6 +2183,27 @@ class MEDCouplingBasicsTest(unittest.TestCase): pass pass + def testCellOrientation3(self): + from cmath import rect + + c = [rect(1.0, i*pi/4.0) for i in range(8)] + coords = [c[-1].real,c[-1].imag, c[3].real,c[3].imag, + c[5].real,c[5].imag, c[1].real,c[1].imag] + connec = [0,1,2,3] + baseMesh = MEDCouplingUMesh.New("circle", 2) + baseMesh.allocateCells(1) + meshCoords = DataArrayDouble.New(coords, 4, 2) + baseMesh.setCoords(meshCoords) + baseMesh.insertNextCell(NORM_QPOLYG, connec) # a circle + baseMesh.finishInsertingCells() + baseMesh.changeSpaceDimension(3) + Oz = [0.0, 0.0, -1.0] + cell_lst = baseMesh.are2DCellsNotCorrectlyOriented(Oz, False) + self.assertEqual(cell_lst.getNumberOfTuples(), 0) + Oz[2] = 1.0 + cell_lst = baseMesh.are2DCellsNotCorrectlyOriented(Oz, False) + self.assertEqual(cell_lst.getNumberOfTuples(), 1) + def testPolyhedronBarycenter(self): connN=[0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0]; coords=[0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5]; @@ -5999,13 +6020,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): else: self.assertTrue(False) pass - try: - da2=da[5:8,-2] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass + self.assertTrue(da[5:8,-2].isEqualWithoutConsideringStr(DataArrayInt([23,26,29]))) da2=da[5:8,:-2] self.assertEqual([22, 25, 28],da2.getValues()) try: @@ -6054,13 +6069,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): else: self.assertTrue(False) pass - try: - da2=da[5:8,-2] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass + self.assertTrue(da[5:8,-2].isEqualWithoutConsideringStr(DataArrayDouble([23.,26.,29.]),1e-12)) da2=da[5:8,:-2] self.assertEqual([22., 25., 28.],da2.getValues()) try: @@ -9562,13 +9571,13 @@ class MEDCouplingBasicsTest(unittest.TestCase): def testSwigGetItem3(self): da=DataArrayInt.New([4,5,6]) self.assertEqual(5,da[1]) - self.assertRaises(InterpKernelException,da.__getitem__,-1) + self.assertEqual(6,da[-1]) self.assertRaises(InterpKernelException,da.__getitem__,3) da=DataArrayInt.New([4,5,6,7,8,9],2,3) self.assertEqual(9,da[1,2]) da=DataArrayDouble.New([4.1,5.2,6.3]) self.assertAlmostEqual(5.2,da[1],12) - self.assertRaises(InterpKernelException,da.__getitem__,-1) + self.assertAlmostEqual(6.3,da[-1],12) self.assertRaises(InterpKernelException,da.__getitem__,3) da=DataArrayDouble.New([4.12,5.12,6.12,7.12,8.12,9.12],2,3) self.assertAlmostEqual(9.12,da[1,2],12) @@ -10419,6 +10428,35 @@ class MEDCouplingBasicsTest(unittest.TestCase): # Check coordinates: self.assertTrue(m3.getCoords().isEqual(m5.getCoords(), eps)) + def testIntersect2DMeshesTmp7(self): + eps = 1.0e-8 + coords = [-0.5,-0.5, -0.5, 0.5, 0.5, 0.5, 0.5,-0.5] + connec = range(4) + m1 = MEDCouplingUMesh.New("box", 2) + m1.allocateCells(1) + meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) + m1.setCoords(meshCoords) + m1.insertNextCell(NORM_POLYGON, connec) + m1.finishInsertingCells() + + m2 = MEDCouplingDataForTest.buildCircle(0.25, 0.2, 0.4) + # Was looping indefinitly: + m_intersec, resToM1, resToM2 = MEDCouplingUMesh.Intersect2DMeshes(m1, m2, eps) + m_intersec.zipCoords() + coo_tgt = DataArrayDouble([-0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.03284271247461901, 0.4828427124746191, + -0.014575131106459124, 0.5000000000000001, 0.5, -0.11224989991991996, 0.24271243444677046, 0.5, 0.5, 0.19387505004004, + -0.04799910280454185, -0.06682678787499614, -0.023843325638122054, 0.4915644577163915, 0.5, -0.30612494995996, 0.0, -0.5, + -0.5, 0.0, -0.25728756555322957, 0.5, -0.023843325638122026, 0.49156445771639157, -0.04799910280454181, -0.06682678787499613], 17 ,2) + conn_tgt = [32, 5, 2, 6, 4, 7, 8, 9, 10, 32, 6, 3, 0, 1, 5, 4, 11, 12, 13, 14, 15, 16] + connI_tgt = [0, 9, 22] + res1_tgt = [0, 0] + res2_tgt = [0, -1] + self.assert_(coo_tgt.isEqualWithoutConsideringStr(m_intersec.getCoords(), 1e-12)) + self.assertEqual(conn_tgt, m_intersec.getNodalConnectivity().getValues()) + self.assertEqual(connI_tgt, m_intersec.getNodalConnectivityIndex().getValues()) + self.assertEqual(res1_tgt, resToM1.getValues()) + self.assertEqual(res2_tgt, resToM2.getValues()) + def testDAIBuildUnique1(self): d=DataArrayInt([1,2,2,3,3,3,3,4,5,5,7,7,7,19]) e=d.buildUnique() @@ -14210,6 +14248,273 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(c.getSpaceDimension(),1) pass + def testSwig2BuildSpreadZonesWithPolyOnQPolyg1(self): + nx=6 + ny=6 + m=MEDCouplingCMesh() + arr1=DataArrayDouble(nx) ; arr1.iota() + arr2=DataArrayDouble(ny) ; arr2.iota() + m.setCoords(arr1,arr2) + m=m.buildUnstructured() + da=DataArrayInt.Range(nx-1,(nx-1)*(ny-1),nx) + m2=m[da] ; m2.simplexize(0) + dan=da.buildComplement(m.getNumberOfCells()) + m1=m[dan] + m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) + # + m.convertLinearCellsToQuadratic() + m1=m[::2] ; m2=m[1::2] ; m2.convertAllToPoly() + m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) + p=m.buildSpreadZonesWithPoly() + self.assertTrue(p.getNodalConnectivity().isEqual(DataArrayInt([32,1,0,6,12,18,24,30,31,32,33,34,35,29,23,17,11,5,4,3,2,36,37,94,62,72,83,84,86,89,99,92,93,82,71,60,51,49,46,43,40]))) + self.assertTrue(p.getNodalConnectivityIndex().isEqual(DataArrayInt([0,41]))) + self.assertTrue(p.getCoords().isEqual(DataArrayDouble([0.,0.,1.,0.,2.,0.,3.,0.,4.,0.,5.,0.,0.,1.,1.,1.,2.,1.,3.,1.,4.,1.,5.,1.,0.,2.,1.,2.,2.,2.,3.,2.,4.,2.,5.,2.,0.,3.,1.,3.,2.,3.,3.,3.,4.,3.,5.,3.,0.,4.,1.,4.,2.,4.,3.,4.,4.,4.,5.,4.,0.,5.,1.,5.,2.,5.,3.,5.,4.,5.,5.,5.,0.5,0.,0.,0.5,0.5,1.,1.,0.5,1.5,0.,1.5,1.,2.,0.5,2.5,0.,2.5,1.,3.,0.5,3.5,0.,3.5,1.,4.,0.5,4.5,0.,4.5,1.,5.,0.5,1.,1.5,1.5,2.,2.,1.5,2.5,2.,3.,1.5,3.5,2.,4.,1.5,4.5,2.,5.,1.5,0.5,2.,0.,2.5,0.5,3.,1.,2.5,2.,2.5,2.5,3.,3.,2.5,3.5,3.,4.,2.5,4.5,3.,5.,2.5,0.,3.5,0.5,4.,1.,3.5,1.5,3.,1.5,4.,2.,3.5,3.,3.5,3.5,4.,4.,3.5,4.5,4.,5.,3.5,0.,4.5,0.5,5.,1.,4.5,1.5,5.,2.,4.5,2.5,4.,2.5,5.,3.,4.5,4.,4.5,4.5,5.,5.,4.5,0.,1.5,0.5,1.5,1.5,2.5,2.5,3.5,3.5,4.5,3.5,5.0],100,2),1e-13)) + pass + + def testSwig2Conformize2D1(self): + eps = 1.0e-8 + coo = [0.,-0.5,0.,0.,0.5,0.,0.5,-0.5,0.25, + -0.1,0.25,0.,0.5,-0.1,0.,0.5,0.5,0.5,0.25,0.4,0.25,0.5,0.5,0.4] + conn = [5,5,2,6,4,5,6,3,0,1,5,4,5,10,8,11,9,5,11,2,1,7,10,9] + connI = [0,5,12,17,24] + m = MEDCouplingUMesh("box",2) + cooArr = DataArrayDouble(coo,len(coo)/2,2) + m.setCoords(cooArr) + m.setConnectivity(DataArrayInt(conn),DataArrayInt(connI)) + m.mergeNodes(eps) + m.checkCoherency() + self.assertTrue(m.conformize2D(eps).isEqual(DataArrayInt([3]))) + self.assertEqual(m.getCoords().getHiddenCppPointer(),cooArr.getHiddenCppPointer()) # check that coordinates remain the same here + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([5,5,2,6,4,5,6,3,0,1,5,4,5,10,8,11,9,5,11,2,5,1,7,10,9]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,12,17,25]))) + pass + + def testSwig2Conformize2D2(self): + eps = 1.0e-8 + coo=DataArrayDouble([-10,-6,0,-6,0,0,7,0,-10,2,0,2,0,6,7,6,0,8,7,8,-10,12,-4,12,0,12,0,11,7,11,-4,16,0,16,7,16],18,2) + conn=DataArrayInt([2,3,7,6, 13,16,17,14, 4,10,12,5, 9,14,13,8, 8,9,7,6, 5,4,0,1, 16,12,11,15]) + m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) + m.setCoords(coo) + m.setNodalConnectivity(conn) + m=m.buildUnstructured() + self.assertTrue(m.conformize2D(eps).isEqual(DataArrayInt([0,1,2,5]))) + self.assertEqual(m.getCoords().getHiddenCppPointer(),coo.getHiddenCppPointer()) # check that coordinates remain the same here + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([5,2,3,7,6,5, 5,13,12,16,17,14, 5,4,10,11,12,13,8,6,5, 4,9,14,13,8, 4,8,9,7,6, 5,5,4,0,1,2, 4,16,12,11,15]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,6,12,21,26,31,37,42]))) + pass + + def testSwigSplit2DCells1(self): + coo=DataArrayDouble([[0,0],[1,0],[1,1],[0,1],[0.5,0],[1,0.5],[0.5,1],[0.,0.5]]) + m=MEDCouplingUMesh("mesh",2) + m.setCoords(coo) + m.allocateCells() + m.insertNextCell(NORM_QUAD8,[0,1,2,3,4,5,6,7]) + _,d,di,_,_=m.buildDescendingConnectivity() + subb=DataArrayInt([5]) + subbi=DataArrayInt([0,0,1,1,1]) + mid=DataArrayInt([-1,-1]) + midi=DataArrayInt([0,0,2,2,2]) + self.assertEqual(2,m.split2DCells(d,di,subb,subbi,mid,midi)) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([32,0,1,5,2,3,4,8,9,6,7]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,11]))) + self.assertTrue(m.getCoords().isEqual(DataArrayDouble([[0,0],[1,0],[1,1],[0,1],[0.5,0],[1,0.5],[0.5,1],[0.,0.5],[1.,0.25],[1.,0.75]]),1e-12)) + pass + + def testSwig2Conformize2D3(self): + eps = 1.0e-8 + coo=DataArrayDouble([-10,-6,0,-6,0,0,7,0,-10,2,0,2,0,6.5,7,6.5,0,8,7,8,-10,12,-4,12,0,12,0,11,7,11,-4,16,0,16,7,16],18,2) + conn=DataArrayInt([2,3,7,6, 13,16,17,14, 4,10,12,5, 9,14,13,8, 8,9,7,6, 5,4,0,1, 16,12,11,15]) + m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) + m.setCoords(coo) + m.setNodalConnectivity(conn) + m=m.buildUnstructured() + m.convertLinearCellsToQuadratic() + self.assertTrue(m.conformize2D(eps).isEqual(DataArrayInt([0,1,2,5]))) + self.assertTrue(m.getCoords().getHiddenCppPointer()!=coo.getHiddenCppPointer()) # coordinates are not the same here contrary to testSwig2Conformize2D2 ... + self.assertTrue(m.getCoords()[:18].isEqual(coo,1e-12)) # but the 18 first nodes are the same + pass + + def testSwig2Conformize2D4(self): + eps = 1.0e-8 + coo=DataArrayDouble([-10,-6,0,-6,0,0,7,0,-10,2,0,2,0,6.5,7,6.5,0,8,7,8,-10,12,-4,12,0,12,0,11,7,11,-4,16,0,16,7,16],18,2) + conn=DataArrayInt([2,3,7,6, 13,16,17,14, 4,10,12,5, 9,14,13,8, 8,9,7,6, 5,4,0,1, 16,12,11,15]) + m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) + m.setCoords(coo) + m.setNodalConnectivity(conn) + m=m.buildUnstructured() + m.convertLinearCellsToQuadratic() + self.assertEqual(42,m.getNumberOfNodes()) + oldCoo=m.getCoords().deepCpy() + m.conformize2D(eps) + self.assertTrue(m.getCoords()[:42].isEqual(oldCoo,1e-12)) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([32,2,3,7,6,5,18,19,20,42,43,32,13,12,16,17,14,44,38,23,24,25,32,4,10,11,12,13,8,6,5,26,45,39,44,31,34,42,29,8,9,14,13,8,30,25,31,32,8,8,9,7,6,32,33,20,34,32,5,4,0,1,2,29,35,36,46,43,8,16,12,11,15,38,39,40,41]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,11,22,39,48,57,68,77]))) + self.assertTrue(m.getCoords().isEqual(DataArrayDouble([[-10.,-6.0],[0.,-6.0],[0.,0.0],[7.,0.0],[-10.,2.0],[0.,2.0],[0.,6.5],[7.,6.5],[0.,8.0],[7.,8.0],[-10.,12.0],[-4.,12.0],[0.,12.0],[0.,11.0],[7.,11.0],[-4.,16.0],[0.,16.0],[7.,16.0],[3.5, 0.0],[7.,3.25],[3.5, 6.5],[0.,3.25],[0.,13.5],[3.5, 16.0],[7.,13.5],[3.5, 11.0],[-10.,7.0],[-5.,12.0],[0.,7.0],[-5.,2.0],[7.,9.5],[0.,9.5],[3.5, 8.0],[7.,7.25],[0.,7.25],[-10.,-2.0],[-5.,-6.0],[0.,-2.0],[0.,14.0],[-2.,12.0],[-4.,14.0],[-2.,16.0],[0.,4.25],[0.,1.0],[0.,11.5],[-7.,12.0],[0.,-3.]]),1e-12)) + pass + + def testSwig2Conformize2D5(self): + eps=1e-8 + coo=DataArrayDouble([[2,2],[2,-6],[10,-2],[-2,-2],[6,0],[6,-4],[2,7],[2,4.5],[-1.4641016151377544,0],[-1.950753362380551,-1.3742621398390762],[-7,-3],[-0.8284271247461898,-4.82842712474619],[0.26794919243112281,3.5],[0,1.4641016151377548],[-4.4753766811902755,-2.1871310699195381],[-3.9142135623730949,-3.9142135623730949],[-1.8042260651806146,-3.23606797749979]]) + m=MEDCouplingUMesh("mesh",2) + m.allocateCells() + m.setCoords(coo) + m.insertNextCell(NORM_TRI6,[1,2,0,5,4,3]) + m.insertNextCell(NORM_TRI6,[8,6,0,12,7,13]) + m.insertNextCell(NORM_TRI6,[11,9,10,16,14,15]) + self.assertTrue(m.conformize2D(eps).isEqual(DataArrayInt([0]))) + self.assertTrue(m.getCoords().isEqual(DataArrayDouble([2.,2.,2.,-6.,10.,-2.,-2.,-2.,6.,0.,6.,-4.,2.,7.,2.,4.5,-1.4641016151377544,0.,-1.950753362380551,-1.3742621398390762,-7.,-3.,-0.8284271247461898,-4.82842712474619,0.2679491924311228,3.5,8.881784197001252e-16,1.4641016151377548,-4.4753766811902755,-2.187131069919538,-3.914213562373095,-3.914213562373095,-1.8042260651806146,-3.236067977499789,-1.7705659643687133,-0.6647725630649153,0.46926627053963865,-5.695518130045146],19,2),1e-12)) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([32,1,2,0,8,9,11,5,4,13,17,16,18,6,8,6,0,12,7,13,6,11,9,10,16,14,15]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,13,20,27]))) + pass + + def testSwigExtendedSlice1(self): + d=DataArrayInt([5,6,7]) + self.assertTrue(d[2:].isEqual(DataArrayInt([7]))) + self.assertTrue(d[3:].isEqual(DataArrayInt([]))) + try: + d[4:] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + d=DataArrayInt([5,6,7,8]) + self.assertEqual(d[-1],8) + self.assertEqual(d[-4],5) + try: + d[-5] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + self.assertTrue(d[2::-1].isEqual(DataArrayInt([7,6,5]))) + self.assertTrue(d[0::-1].isEqual(DataArrayInt([5]))) + self.assertTrue(d[-1::-1].isEqual(DataArrayInt([8,7,6,5]))) + self.assertTrue(d[-3::-1].isEqual(DataArrayInt([6,5]))) + self.assertTrue(d[-5::-1].isEqual(DataArrayInt([]))) + try: + d[-6::-1] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + d=DataArrayInt([]) + self.assertTrue(d[0:].isEqual(DataArrayInt([]))) + # + d=DataArrayDouble([5,6,7]) + self.assertTrue(d[2:].isEqual(DataArrayDouble([7]),1e-12)) + self.assertTrue(d[3:].isEqual(DataArrayDouble([]),1e-12)) + try: + d[4:] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + d=DataArrayDouble([5,6,7,8]) + self.assertAlmostEqual(d[-1],8.,12) + self.assertAlmostEqual(d[-4],5.,12) + try: + d[-5] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + self.assertTrue(d[2::-1].isEqual(DataArrayDouble([7,6,5]),1e-12)) + self.assertTrue(d[0::-1].isEqual(DataArrayDouble([5]),1e-12)) + self.assertTrue(d[-1::-1].isEqual(DataArrayDouble([8,7,6,5]),1e-12)) + self.assertTrue(d[-3::-1].isEqual(DataArrayDouble([6,5]),1e-12)) + self.assertTrue(d[-5::-1].isEqual(DataArrayDouble([]),1e-12)) + try: + d[-6::-1] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + d=DataArrayDouble([]) + self.assertTrue(d[0:].isEqual(DataArrayDouble([]),1e-12)) + pass + + def testSwig2Hexa27GP1(self): + """ This test focused on shape functions of hexa27. + """ + coo=DataArrayDouble([[0.,2.,2.],[0.,0.,2.],[2.,0.,2.],[2.,2.,2.],[0.,2.,0.],[0.,0.,0.],[2.,0.,0.],[2.,2.,0.], [0.,1.,2.],[1.,0.,2.],[2.,1.,2.],[1.,2.,2.], [0.,1.,0.],[1.,0.,0.],[2.,1.,0.],[1.,2.,0.], [0.,2.,1.],[0.,0.,1.],[2.,0.,1.],[2.,2.,1.], [1.,1.,2.], [0.,1.,1.],[1.,0.,1.],[2.,1.,1.],[1.,2.,1.], [1.,1.,0.], [1.,1.,1.]]) + m=MEDCouplingUMesh("mesh",3) ; m.setCoords(coo) + m.allocateCells() + # the cell description is exactly those described in the description of HEXA27 in MED file 3.0.7 documentation + m.insertNextCell(NORM_HEXA27,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]) + refCoo=[-1.,-1.,-1.,-1.,1.,-1.,1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,-1.,1.,1.,1.,1.,1.,1.,-1.,1.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.] + weights=[0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.7023319615912209,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571] + gCoords=[-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,0.0,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.0,0.0,0.0,0.0,0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,0.0,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483] + fGauss=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fGauss.setName("fGauss") + fGauss.setMesh(m) + fGauss.setGaussLocalizationOnType(NORM_HEXA27,refCoo,gCoords,weights) + arr=DataArrayDouble(fGauss.getNumberOfTuplesExpected()) ; arr.iota() + fGauss.setArray(arr) + arrOfDisc=fGauss.getLocalizationOfDiscr() + # the test is here + self.assertTrue(arrOfDisc.isEqual(DataArrayDouble([0.2254033307585172,1.7745966692414836,1.7745966692414834,0.22540333075851715,1.7745966692414834,1.,0.22540333075851715,1.7745966692414836,0.22540333075851715,0.22540333075851715,1.,1.7745966692414834,0.2254033307585171,1.,1.,0.22540333075851715,1.0000000000000002,0.2254033307585171,0.22540333075851715,0.22540333075851715,1.7745966692414838,0.22540333075851715,0.22540333075851715,1.,0.22540333075851715,0.22540333075851715,0.22540333075851715,1.,1.7745966692414832,1.7745966692414834,1.,1.774596669241483,1.,1.0000000000000002,1.7745966692414832,0.22540333075851712,1.,1.,1.774596669241483,1.,1.,1.,1.,1.,0.2254033307585171,1.,0.22540333075851715,1.7745966692414834,1.,0.2254033307585171,1.,1.0000000000000002,0.22540333075851715,0.2254033307585171,1.7745966692414834,1.7745966692414834,1.7745966692414836,1.7745966692414832,1.7745966692414834,1.0000000000000002,1.7745966692414834,1.7745966692414836,0.22540333075851712,1.7745966692414832,1.,1.7745966692414834,1.774596669241483,1.,1.,1.7745966692414832,1.0000000000000002,0.22540333075851712,1.7745966692414836,0.22540333075851715,1.7745966692414836,1.7745966692414832,0.22540333075851715,1.,1.7745966692414836,0.22540333075851715,0.22540333075851715],27,3),1e-12)) + # + weights=27*[1] + gCoords=refCoo + fGauss.setGaussLocalizationOnType(NORM_HEXA27,refCoo,gCoords,weights) + arrOfDisc2=fGauss.getLocalizationOfDiscr() + self.assertTrue(arrOfDisc2.isEqual(coo,1e-12)) + pass + + def testSwig2Pyra13GP1(self): + coo=DataArrayDouble([[0.,2.,0.],[2.,2.,0.],[2.,0.,0.],[0.,0.,0.],[1.,1.,2.],[1.,2.,0.],[2.,1.,0.],[1.,0.,0.],[0.,1.,0.],[0.5,1.5,1.],[1.5,1.5,1.],[1.5,0.5,1.],[0.5,0.5,1.]]) + m=MEDCouplingUMesh("mesh",3) ; m.setCoords(coo) + m.allocateCells() + # the cell description is exactly those described in the description of PYRA13 in MED file 3.0.7 documentation + m.insertNextCell(NORM_PYRA13,[0,1,2,3,4,5,6,7,8,9,10,11,12]) + refCoords=[1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,1.,0.5,-0.5,0.,-0.5,-0.5,0.,-0.5,0.5,0.,0.5,0.5,0.,0.5,0.,0.5,0.,-0.5,0.5,-0.5,0.,0.5,0.,0.5,0.5] + gaussCoords=[0.,0.,0.5,0.21210450275,0.21210450275,0.5,-0.21210450275,0.21210450275,0.5,-0.21210450275,-0.21210450275,0.5,0.21210450275,-0.21210450275,0.5,0.,0.,0.07579099449999999,0.,0.,0.9242090055000001,0.5394929090572634,0.,0.17359176399999998,0.,0.5394929090572634,0.17359176399999998,-0.5394929090572634,0.,0.17359176399999998,0.,-0.5394929090572634,0.17359176399999998,0.1133235629427366,0.,0.826408236,0.,0.1133235629427366,0.826408236,-0.1133235629427366,0.,0.826408236,0.,-0.1133235629427366,0.826408236,0.5826406005183961,0.5826406005183961,-0.053206449499999975,-0.5826406005183961,0.5826406005183961,-0.053206449499999975,-0.5826406005183961,-0.5826406005183961,-0.053206449499999975,0.5826406005183961,-0.5826406005183961,-0.053206449499999975,0.5532064495,0.,0.5,0.,0.5532064495,0.5,-0.5532064495,0.,0.5,0.,-0.5532064495,0.5,-0.029434151018396033,-0.029434151018396033,1.0532064495,0.029434151018396033,-0.029434151018396033,1.0532064495,0.029434151018396033,0.029434151018396033,1.0532064495,-0.029434151018396033,0.029434151018396033,1.0532064495] + weights=[0.0492545926875,0.031210562625,0.031210562625,0.031210562625,0.031210562625,0.10663554205740113,0.0007171281994273535,0.0816994048010844,0.0816994048010844,0.0816994048010844,0.0816994048010844,0.0036048554264914074,0.0036048554264914074,0.0036048554264914074,0.0036048554264914074,0.008958181586640837,0.008958181586640837,0.008958181586640837,0.008958181586640837,0.002018983875,0.002018983875,0.002018983875,0.002018983875,2.286237794882217e-05,2.286237794882217e-05,2.286237794882217e-05,2.286237794882217e-05] + fGauss=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fGauss.setName("fGauss") + fGauss.setMesh(m) + fGauss.setGaussLocalizationOnType(NORM_PYRA13,refCoords,gaussCoords,weights) + arr=DataArrayDouble(fGauss.getNumberOfTuplesExpected()) ; arr.iota() + fGauss.setArray(arr) + arrOfDisc=fGauss.getLocalizationOfDiscr() + # the test is here + self.assertTrue(arrOfDisc.isEqual(DataArrayDouble([1.,1.,1.,0.5757909945,1.,1.,1.,0.5757909945,1.,1.4242090055,1.,1.,1.,1.4242090055,1.,1.,1.,0.151581989,1.,1.,1.848418011,0.4605070909427367,1.5394929090572635,0.347183528,0.4605070909427367,0.4605070909427367,0.347183528,1.5394929090572638,0.4605070909427366,0.347183528,1.5394929090572635,1.5394929090572638,0.347183528,0.8866764370572636,1.1133235629427367,1.652816472,0.8866764370572636,0.8866764370572636,1.652816472,1.1133235629427367,0.8866764370572636,1.652816472,1.1133235629427365,1.1133235629427367,1.652816472,-0.16528120103679209,1.,-0.106412899,1.,-0.1652812010367921,-0.106412899,2.1652812010367914,1.,-0.106412899,1.,2.165281201036791,-0.106412899,0.4467935505,1.5532064495,1.,0.4467935505,0.4467935505,1.,1.5532064495,0.4467935505,1.,1.5532064495,1.5532064495,1.,1.0588683020367922,1.,2.106412899,1.,1.0588683020367922,2.106412899,0.9411316979632077,1.,2.106412899,1.,0.9411316979632078,2.106412899],27,3),1e-12)) + # + weights=13*[1] + gaussCoords=refCoords[:] ; gaussCoords[14]=0.9999999999999 # change z of point #4 0.999... instead of 1. because with shape function it leads to division by 0. ! + fGauss.setGaussLocalizationOnType(NORM_PYRA13,refCoords,gaussCoords,weights) + arrOfDisc2=fGauss.getLocalizationOfDiscr() + self.assertTrue(arrOfDisc2.isEqual(coo,1e-10)) # be less exigent 1e-10 instead of 1e-12 due to shape function sensitivity arount 0.,0.,1. ! + pass + + def testSwig2Tri7GP1(self): + coo=DataArrayDouble([[0,0],[0,2],[2,0],[0,1],[1,1],[1,0],[0.6666666666666667,0.6666666666666667]]) + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo) + m.allocateCells() + # the cell description is exactly those described in the description of TRI7 in MED file 3.0.7 documentation + m.insertNextCell(NORM_TRI7,range(7)) + refCoords=[0.,0.,1.,0.,0.,1.,0.5,0.,0.5,0.5,0.,0.5,0.3333333333333333,0.3333333333333333] + gaussCoords=[0.3333333333333333,0.3333333333333333,0.470142064105115,0.470142064105115,0.05971587178977,0.470142064105115,0.470142064105115,0.05971587178977,0.101286507323456,0.101286507323456,0.797426985353088,0.101286507323456,0.101286507323456,0.797426985353088] + weights=[0.062969590272413,0.062969590272413,0.062969590272413,0.066197076394253,0.066197076394253,0.066197076394253,0.1125] + fGauss=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fGauss.setName("fGauss") + fGauss.setMesh(m) + fGauss.setGaussLocalizationOnType(NORM_TRI7,refCoords,gaussCoords,weights) + arr=DataArrayDouble(fGauss.getNumberOfTuplesExpected()) ; arr.iota() + fGauss.setArray(arr) + arrOfDisc=fGauss.getLocalizationOfDiscr() + self.assertTrue(arrOfDisc.isEqual(DataArrayDouble([0.666666666666667,0.666666666666667,0.9402841282102293,0.9402841282102293,0.9402841282102299,0.11943174357954002,0.11943174357953992,0.9402841282102299,0.20257301464691194,0.20257301464691196,0.20257301464691205,1.5948539707061757,1.5948539707061757,0.20257301464691202],7,2),1e-12)) + # + weights=7*[1] + gaussCoords=refCoords + fGauss.setGaussLocalizationOnType(NORM_TRI7,refCoords,gaussCoords,weights) + arrOfDisc2=fGauss.getLocalizationOfDiscr() + self.assertTrue(arrOfDisc2.isEqual(coo,1e-12)) + pass + def setUp(self): pass pass diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index 8723563df..81c0a6fd0 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -238,6 +238,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGradually; %newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed; %newobject ParaMEDMEM::MEDCouplingUMesh::buildNewNumberingFromCommNodesFrmt; +%newobject ParaMEDMEM::MEDCouplingUMesh::conformize2D; %newobject ParaMEDMEM::MEDCouplingUMesh::rearrange2ConsecutiveCellTypes; %newobject ParaMEDMEM::MEDCouplingUMesh::sortCellsInMEDFileFrmt; %newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForMEDFileFrmt; @@ -270,6 +271,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingUMesh::buildUnionOf3DMesh; %newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTreeFast; %newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic; +%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic; %newobject ParaMEDMEM::MEDCouplingUMeshCellByTypeEntry::__iter__; %newobject ParaMEDMEM::MEDCouplingUMeshCellEntry::__iter__; %newobject ParaMEDMEM::MEDCoupling1GTUMesh::New; @@ -1500,6 +1502,7 @@ namespace ParaMEDMEM std::string reprConnectivityOfThis() const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); //tools + DataArrayInt *conformize2D(double eps) throw(INTERP_KERNEL::Exception); void shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Exception); std::vector getQuadraticStatus() const throw(INTERP_KERNEL::Exception); DataArrayInt *findCellIdsOnBoundary() const throw(INTERP_KERNEL::Exception); @@ -1540,6 +1543,8 @@ namespace ParaMEDMEM DataArrayInt *buildUnionOf3DMesh() const throw(INTERP_KERNEL::Exception); DataArrayDouble *getBoundingBoxForBBTreeFast() const throw(INTERP_KERNEL::Exception); DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); + int split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt=0, const DataArrayInt *midOptI=0) throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); @@ -2075,8 +2080,7 @@ namespace ParaMEDMEM arrIndxIn->checkAllocated(); if(arrIndxIn->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : number of components of last argument must be equal to one !"); - if(PySlice_GetIndices(sliC,arrIndxIn->getNumberOfTuples(),&strt,&stp,&step)!=0) - throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : Invalid slice regarding nb of elements !"); + GetIndicesOfSlice(sliC,arrIndxIn->getNumberOfTuples(),&strt,&stp,&step,"ExtractFromIndexedArrays2 (wrap) : Invalid slice regarding nb of elements !"); DataArrayInt *arrOut=0,*arrIndexOut=0; MEDCouplingUMesh::ExtractFromIndexedArrays2(strt,stp,step,arrIn,arrIndxIn,arrOut,arrIndexOut); PyObject *ret=PyTuple_New(2); diff --git a/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i index f71939e90..76d2b4635 100644 --- a/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i +++ b/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i @@ -20,6 +20,53 @@ #include "InterpKernelAutoPtr.hxx" +/*! + * This method is an extention of PySlice_GetIndices but less + * open than PySlice_GetIndicesEx that accepts too many situations. + */ +void GetIndicesOfSlice(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, const char *msgInCaseOfFailure) +{ + int ret(PySlice_GetIndices(slice,length,start,stop,step)); + if(ret==0) + return ; + if(*step>0 && *start==*stop && length==*start) + return ; + throw INTERP_KERNEL::Exception(msgInCaseOfFailure); +} + +/*! + * This method allows to retrieve slice info from \a slice. + */ +void GetIndicesOfSliceExplicitely(PySliceObject *slice, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, const char *msgInCaseOfFailure) +{ + int ret(PySlice_GetIndices(slice,std::numeric_limits::max(),start,stop,step)); + if(ret==0) + { + if(*start!=std::numeric_limits::max() && *stop!=std::numeric_limits::max()) + return ; + std::ostringstream oss; + oss << msgInCaseOfFailure << " The input slice contains some unknowns that can't be determined in static method ! The input slice must be explicit here !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + throw INTERP_KERNEL::Exception(msgInCaseOfFailure); +} + +int InterpreteNegativeInt(int val, int nbelem) +{ + if(val<0) + { + int newVal(nbelem+val); + if(newVal<0) + { + std::ostringstream oss; oss << "interpreteNegativeInt : request for negative int=" << val << " but number of elems is equal to " << nbelem << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return newVal; + } + else + return val; +} + #ifdef WITH_NUMPY #include @@ -270,7 +317,9 @@ MCData *BuildNewInstance(PyObject *elt0, int npyObjectType, PyTypeObject *pytype { ret->useArray(reinterpret_cast(data),true,ParaMEDMEM::C_DEALLOC,sz0,sz1); PyObject *ref=PyWeakref_NewRef(reinterpret_cast(eltOwning),NULL); - void **objs=new void *[2]; objs[0]=ref; objs[1]=(void*) ParaMEDMEM::MemArray::CDeallocator; + typename ParaMEDMEM::MemArray::Deallocator tmp(ParaMEDMEM::MemArray::CDeallocator); + void **tmp2(reinterpret_cast(&tmp)); + void **objs=new void *[2]; objs[0]=ref; objs[1]=*tmp2; mma.setParameterForDeallocator(objs); mma.setSpecificDeallocator(numarrdeal); } @@ -368,13 +417,15 @@ PyObject *ToNumPyArray(MCData *self, int npyObjectType, const char *MCDataStr) npy_intp dim[2]; dim[0]=(npy_intp)self->getNumberOfTuples(); dim[1]=nbComp; const T *bg=self->getConstPointer(); - PyObject *ret=PyArray_SimpleNewFromData(nbDims,dim,npyObjectType,const_cast(bg)); + PyObject *ret(PyArray_SimpleNewFromData(nbDims,dim,npyObjectType,const_cast(bg))); if(mem.isDeallocatorCalled()) { if(mem.getDeallocator()!=numarrdeal) {// case for the first call of toNumPyArray - PyObject *ref=PyWeakref_NewRef(ret,NULL); - void **objs=new void *[2]; objs[0]=ref; objs[1]=(void*) mem.getDeallocator(); + PyObject *ref(PyWeakref_NewRef(ret,NULL)); + typename ParaMEDMEM::MemArray::Deallocator tmp(mem.getDeallocator()); + void **tmp2(reinterpret_cast(&tmp)); + void **objs=new void *[2]; objs[0]=reinterpret_cast(ref); objs[1]=*tmp2; mem.setParameterForDeallocator(objs); mem.setSpecificDeallocator(numarrdeal); return ret; @@ -1416,12 +1467,7 @@ static void convertObjToPossibleCpp2(PyObject *value, int nbelem, int& sw, int& { Py_ssize_t strt=2,stp=2,step=2; PySliceObject *oC=reinterpret_cast(value); - if(PySlice_GetIndices(oC,nbelem,&strt,&stp,&step)!=0) - if(nbelem!=0 || strt!=0 || stp!=0) - { - std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elements is : " << nbelem; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + GetIndicesOfSlice(oC,nbelem,&strt,&stp,&step,"Slice in subscriptable object DataArray invalid !"); p.first=strt; p.second.first=stp; p.second.second=step; @@ -1458,6 +1504,18 @@ static void convertObjToPossibleCpp2(PyObject *value, int nbelem, int& sw, int& throw INTERP_KERNEL::Exception(msg); } +/*! + * Idem than convertObjToPossibleCpp2 + */ +static void convertObjToPossibleCpp2WithNegIntInterp(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector& stdvecTyypp, std::pair >& p, ParaMEDMEM::DataArrayInt *& daIntTyypp) throw(INTERP_KERNEL::Exception) +{ + convertObjToPossibleCpp2(value,nbelem,sw,iTyypp,stdvecTyypp,p,daIntTyypp); + if(sw==1) + { + iTyypp=InterpreteNegativeInt(iTyypp,nbelem); + } +} + /*! * if python int -> cpp int sw=1 * if python tuple[int] -> cpp vector sw=2 @@ -1514,12 +1572,7 @@ static void convertObjToPossibleCpp22(PyObject *value, int nbelem, int& sw, int& { Py_ssize_t strt=2,stp=2,step=2; PySliceObject *oC=reinterpret_cast(value); - if(PySlice_GetIndices(oC,nbelem,&strt,&stp,&step)!=0) - if(nbelem!=0 || strt!=0 || stp!=0) - { - std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elements is : " << nbelem; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + GetIndicesOfSlice(oC,nbelem,&strt,&stp,&step,"Slice in subscriptable object DataArray invalid !"); p.first=strt; p.second.first=stp; p.second.second=step; @@ -1649,7 +1702,7 @@ static void convertObjToPossibleCpp3(PyObject *value, int nbTuple, int nbCompo, { if(!PyTuple_Check(value)) { - convertObjToPossibleCpp2(value,nbTuple,sw,it,vt,pt,dt); + convertObjToPossibleCpp2WithNegIntInterp(value,nbTuple,sw,it,vt,pt,dt); return ; } else @@ -1659,9 +1712,9 @@ static void convertObjToPossibleCpp3(PyObject *value, int nbTuple, int nbCompo, throw INTERP_KERNEL::Exception("Unexpected nb of slice element : 1 or 2 expected !\n1st is for tuple selection, 2nd for component selection !"); PyObject *ob0=PyTuple_GetItem(value,0); int sw1,sw2; - convertObjToPossibleCpp2(ob0,nbTuple,sw1,it,vt,pt,dt); + convertObjToPossibleCpp2WithNegIntInterp(ob0,nbTuple,sw1,it,vt,pt,dt); PyObject *ob1=PyTuple_GetItem(value,1); - convertObjToPossibleCpp2(ob1,nbCompo,sw2,ic,vc,pc,dc); + convertObjToPossibleCpp2WithNegIntInterp(ob1,nbCompo,sw2,ic,vc,pc,dc); sw=4*sw2+sw1; } } diff --git a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py index c888a0d74..5ed647cba 100644 --- a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py @@ -683,6 +683,24 @@ class MEDCouplingDataForTest: fff.setGaussLocalizationOnCells([6,7],[-1.,-1.,-1.,-1.,1.,-1.,1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,-1.,1.,1.,1.,1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626],[1.,1.,1.,1.,1.,1.,1.,1.]) return MEDCouplingFieldTemplate(fff) + def buildCircle(self, center_X, center_Y, radius): + from cmath import rect + from math import pi + + c = [rect(radius, i*pi/4.0) for i in range(8)] + coords = [c[-1].real,c[-1].imag, c[3].real,c[3].imag, + c[5].real,c[5].imag, c[1].real,c[1].imag] + connec = range(4) + baseMesh = MEDCouplingUMesh.New("circle", 2) + baseMesh.allocateCells(1) + meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) + meshCoords += (center_X, center_Y) + baseMesh.setCoords(meshCoords) + + baseMesh.insertNextCell(NORM_QPOLYG, connec) + baseMesh.finishInsertingCells() + return baseMesh + build2DTargetMesh_1=classmethod(build2DTargetMesh_1) build2DSourceMesh_1=classmethod(build2DSourceMesh_1) build3DTargetMesh_1=classmethod(build3DTargetMesh_1) @@ -711,4 +729,8 @@ class MEDCouplingDataForTest: buildFieldOnGauss_2=classmethod(buildFieldOnGauss_2) buildFieldOnGauss_3=classmethod(buildFieldOnGauss_3) buildFieldOnGauss_4=classmethod(buildFieldOnGauss_4) + buildCircle=classmethod(buildCircle) pass + + + diff --git a/src/MEDCoupling_Swig/MEDCouplingMemArray.i b/src/MEDCoupling_Swig/MEDCouplingMemArray.i index 100f477be..c638e76d4 100644 --- a/src/MEDCoupling_Swig/MEDCouplingMemArray.i +++ b/src/MEDCoupling_Swig/MEDCouplingMemArray.i @@ -408,10 +408,7 @@ namespace ParaMEDMEM throw INTERP_KERNEL::Exception("DataArray::GetSlice (wrap) : expecting a pyslice as second (first) parameter !"); Py_ssize_t strt=2,stp=2,step=2; PySliceObject *sly=reinterpret_cast(slic); - if(PySlice_GetIndices(sly,std::numeric_limits::max(),&strt,&stp,&step)!=0) - throw INTERP_KERNEL::Exception("DataArray::GetSlice (wrap) : the input slice is invalid !"); - if(strt==std::numeric_limits::max() || stp==std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("DataArray::GetSlice (wrap) : the input slice contains some unknowns that can't be determined in static method ! Call DataArray::getSlice (non static) instead !"); + GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetSlice (wrap) : the input slice is invalid !"); int a,b; DataArray::GetSlice(strt,stp,step,sliceId,nbOfSlices,a,b); return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(step)); @@ -423,8 +420,7 @@ namespace ParaMEDMEM throw INTERP_KERNEL::Exception("DataArray::getSlice (wrap) : expecting a pyslice as second (first) parameter !"); Py_ssize_t strt=2,stp=2,step=2; PySliceObject *sly=reinterpret_cast(slic); - if(PySlice_GetIndices(sly,self->getNumberOfTuples(),&strt,&stp,&step)!=0) - throw INTERP_KERNEL::Exception("DataArray::getSlice (wrap) : the input slice is invalid !"); + GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getSlice (wrap) : the input slice is invalid !"); int a,b; DataArray::GetSlice(strt,stp,step,sliceId,nbOfSlices,a,b); return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(step)); @@ -436,10 +432,7 @@ namespace ParaMEDMEM throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES (wrap) : expecting a pyslice as second (first) parameter !"); Py_ssize_t strt=2,stp=2,step=2; PySliceObject *sly=reinterpret_cast(slic); - if(PySlice_GetIndices(sly,std::numeric_limits::max(),&strt,&stp,&step)!=0) - throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES (wrap) : the input slice is invalid !"); - if(strt==std::numeric_limits::max() || stp==std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES (wrap) : the input slice contains some unknowns that can't be determined in static method !"); + GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetNumberOfItemGivenBES (wrap) : the input slice is invalid !"); return DataArray::GetNumberOfItemGivenBES(strt,stp,step,""); } @@ -449,10 +442,7 @@ namespace ParaMEDMEM throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBESRelative (wrap) : expecting a pyslice as second (first) parameter !"); Py_ssize_t strt=2,stp=2,step=2; PySliceObject *sly=reinterpret_cast(slic); - if(PySlice_GetIndices(sly,std::numeric_limits::max(),&strt,&stp,&step)!=0) - throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBESRelative (wrap) : the input slice is invalid !"); - if(strt==std::numeric_limits::max() || stp==std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBESRelative (wrap) : the input slice contains some unknowns that can't be determined in static method !"); + GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetNumberOfItemGivenBESRelative (wrap) : the input slice is invalid !"); return DataArray::GetNumberOfItemGivenBESRelative(strt,stp,step,""); } @@ -469,8 +459,7 @@ namespace ParaMEDMEM throw INTERP_KERNEL::Exception("DataArray::getNumberOfItemGivenBES (wrap) : expecting a pyslice as second (first) parameter !"); Py_ssize_t strt=2,stp=2,step=2; PySliceObject *sly=reinterpret_cast(slic); - if(PySlice_GetIndices(sly,self->getNumberOfTuples(),&strt,&stp,&step)!=0) - throw INTERP_KERNEL::Exception("DataArray::getNumberOfItemGivenBES (wrap) : the input slice is invalid !"); + GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getNumberOfItemGivenBES (wrap) : the input slice is invalid !"); return DataArray::GetNumberOfItemGivenBES(strt,stp,step,""); } @@ -480,8 +469,7 @@ namespace ParaMEDMEM throw INTERP_KERNEL::Exception("DataArray::getNumberOfItemGivenBESRelative (wrap) : expecting a pyslice as second (first) parameter !"); Py_ssize_t strt=2,stp=2,step=2; PySliceObject *sly=reinterpret_cast(slic); - if(PySlice_GetIndices(sly,self->getNumberOfTuples(),&strt,&stp,&step)!=0) - throw INTERP_KERNEL::Exception("DataArray::getNumberOfItemGivenBESRelative (wrap) : the input slice is invalid !"); + GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getNumberOfItemGivenBESRelative (wrap) : the input slice is invalid !"); return DataArray::GetNumberOfItemGivenBESRelative(strt,stp,step,""); } } @@ -697,6 +685,7 @@ namespace ParaMEDMEM #endif else throw INTERP_KERNEL::Exception(msg.c_str()); + throw INTERP_KERNEL::Exception(msg.c_str());//to make g++ happy } DataArrayDouble(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) @@ -2270,7 +2259,7 @@ namespace ParaMEDMEM ParaMEDMEM::DataArrayInt *daIntTyypp=0; const double *pt=self->getConstPointer(); int nbc=self->getNumberOfCompo(); - convertObjToPossibleCpp2(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp); + convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp); switch(sw) { case 1: @@ -2339,7 +2328,7 @@ namespace ParaMEDMEM std::pair > slic; ParaMEDMEM::DataArrayInt *daIntTyypp=0; double *pt=self->getPointer(); - convertObjToPossibleCpp2(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp); + convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp); switch(sw2) { case 1: @@ -2704,6 +2693,7 @@ namespace ParaMEDMEM #endif else throw INTERP_KERNEL::Exception(msg.c_str()); + throw INTERP_KERNEL::Exception(msg.c_str());//to make g++ happy } DataArrayInt(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) @@ -2777,8 +2767,7 @@ namespace ParaMEDMEM throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : expecting a pyslice as second (first) parameter !"); Py_ssize_t strt=2,stp=2,step=2; PySliceObject *sly=reinterpret_cast(slic); - if(PySlice_GetIndices(sly,std::numeric_limits::max(),&strt,&stp,&step)!=0) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : the input slice is invalid !"); + GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : the input slice is invalid !"); if(strt==std::numeric_limits::max() || stp==std::numeric_limits::max()) throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : the input slice contains some unknowns that can't be determined in static method ! Call DataArray::getSlice (non static) instead !"); return self->buildExplicitArrOfSliceOnScaledArr(strt,stp,step); @@ -4532,7 +4521,7 @@ namespace ParaMEDMEM ParaMEDMEM::DataArrayInt *daIntTyypp=0; const int *pt=self->getConstPointer(); int nbc=self->getNumberOfCompo(); - convertObjToPossibleCpp2(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp); + convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp); switch(sw) { case 1: @@ -4602,7 +4591,7 @@ namespace ParaMEDMEM std::pair > slic; ParaMEDMEM::DataArrayInt *daIntTyypp=0; int *pt=self->getPointer(); - convertObjToPossibleCpp2(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp); + convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp); switch(sw2) { case 1: @@ -5529,7 +5518,7 @@ namespace ParaMEDMEM std::vector stdvecTyyppArr; std::pair > sTyyppArr; ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(obj,self->getNumberOfTuples(),sw,iTypppArr,stdvecTyyppArr,sTyyppArr,daIntTyypp); + convertObjToPossibleCpp2WithNegIntInterp(obj,self->getNumberOfTuples(),sw,iTypppArr,stdvecTyyppArr,sTyyppArr,daIntTyypp); switch(sw) { case 1: @@ -5554,7 +5543,7 @@ namespace ParaMEDMEM ParaMEDMEM::DataArrayInt *daIntTyypp=0; int nbOfCompo=self->getNumberOfComponents(); int nbOfTuples=self->getNumberOfTuples(); - convertObjToPossibleCpp2(obj,nbOfTuples,sw1,iTypppArr,stdvecTyyppArr,sTyyppArr,daIntTyypp); + convertObjToPossibleCpp2WithNegIntInterp(obj,nbOfTuples,sw1,iTypppArr,stdvecTyyppArr,sTyyppArr,daIntTyypp); int sw2; char vc; std::string sc; std::vector vsc; DataArrayChar *dacc=0; convertObjToPossibleCpp6(value,sw2,vc,sc,vsc,dacc); diff --git a/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py b/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py index e38950f69..b510668ea 100644 --- a/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py @@ -17,7 +17,6 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -# from MEDCoupling import * @@ -32,7 +31,7 @@ import os,gc,weakref,unittest class MEDCouplingNumPyTest(unittest.TestCase): - @unittest.skipUnless(MEDCouplingHasNumPyBindings() and architecture()[0]=="64bit","requires numpy") + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") def test1(self): sz=20 a=array(0,dtype=int32) diff --git a/src/MEDCoupling_Swig/MEDCouplingRemapper.i b/src/MEDCoupling_Swig/MEDCouplingRemapper.i index 91b0add29..863a3bb43 100644 --- a/src/MEDCoupling_Swig/MEDCouplingRemapper.i +++ b/src/MEDCoupling_Swig/MEDCouplingRemapper.i @@ -74,6 +74,7 @@ namespace ParaMEDMEM int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) throw(INTERP_KERNEL::Exception); double getMaxValueInCrudeMatrix() const throw(INTERP_KERNEL::Exception); int getNumberOfColsOfMatrix() const throw(INTERP_KERNEL::Exception); + static std::string BuildMethodFrom(const std::string& meth1, const std::string& meth2) throw(INTERP_KERNEL::Exception); %extend { PyObject *getCrudeMatrix() const throw(INTERP_KERNEL::Exception) diff --git a/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py b/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py index 9d4b26947..ef181bc32 100644 --- a/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py @@ -695,6 +695,71 @@ class MEDCouplingBasicsTest(unittest.TestCase): delta=m0-m1t self.assertTrue(DataArrayDouble(delta.data).isUniform(0.,1e-17)) pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") + def testNonConformWithRemapper_1(self): + coo=DataArrayDouble([-0.396700000780411,-0.134843245350081,-0.0361311386958691,-0.407550009429364,-0.13484324535008,-0.0361311386958923,-0.396700000780411,-0.132191446077668,-0.0448729493559049,-0.407550009429364,-0.132191446077666,-0.0448729493559254,-0.396700000780411,-0.128973582738749,-0.0534226071577727,-0.407550009429364,-0.128973582738747,-0.0534226071577904,-0.396700000780411,-0.128348829636458,-0.0346583696473619,-0.407550009429364,-0.128348829636457,-0.0346583696473822,-0.396700000780411,-0.125874740261886,-0.0430683597970123,-0.407550009429364,-0.125874740261885,-0.0430683597970302,-0.396700000780411,-0.122905344829122,-0.051310216195766,-0.407550009429364,-0.12290534482912,-0.0513102161957814],12,3) + conn=DataArrayInt([2,9,3,11,2,3,5,11,2,8,9,11,2,10,8,11,2,5,4,11,2,4,10,11,3,0,1,6,3,1,7,6,3,2,0,6,3,8,2,6,3,7,9,6,3,9,8,6]) + m=MEDCoupling1SGTUMesh("mesh",NORM_TETRA4) + m.setNodalConnectivity(conn) + m.setCoords(coo) + # m is ready + m1,d,di,rd,rdi=m.buildUnstructured().buildDescendingConnectivity() + rdi2=rdi.deltaShiftIndex() + cellIds=rdi2.getIdsEqual(1) + skinAndNonConformCells=m1[cellIds] + skinAndNonConformCells.zipCoords() # at this point skinAndNonConformCells contains non conform cells and skin cells. Now trying to split them in two parts. + # + rem=MEDCouplingRemapper() + rem.setMaxDistance3DSurfIntersect(1e-12) + rem.setMinDotBtwPlane3DSurfIntersect(0.99)# this line is important it is to tell to remapper to select only cells with very close orientation + rem.prepare(skinAndNonConformCells,skinAndNonConformCells,"P0P0") + mat=rem.getCrudeCSRMatrix() + indptr=DataArrayInt(mat.indptr) + indptr2=indptr.deltaShiftIndex() + cellIdsOfNonConformCells=indptr2.getIdsNotEqual(1) + cellIdsOfSkin=indptr2.getIdsEqual(1) + self.assertTrue(cellIdsOfSkin.isEqual(DataArrayInt([1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20,21,23]))) + self.assertTrue(cellIdsOfNonConformCells.isEqual(DataArrayInt([0,4,18,22]))) + pass + + def test3D1DOnP1P0_1(self): + """ This test focused on P1P0 interpolation with a source with meshDim=1 spaceDim=3 and a target with meshDim=3. + This test has revealed a bug in remapper. A reverse matrix is computed so a reverse method should be given in input. + """ + target=MEDCouplingCMesh() + arrX=DataArrayDouble([0,1]) ; arrY=DataArrayDouble([0,1]) ; arrZ=DataArrayDouble(11) ; arrZ.iota() + target.setCoords(arrX,arrY,arrZ) + target=target.buildUnstructured() ; target.setName("TargetSecondaire") + # + sourceCoo=DataArrayDouble([(0.5,0.5,0.1),(0.5,0.5,1.2),(0.5,0.5,1.6),(0.5,0.5,1.8),(0.5,0.5,2.43),(0.5,0.5,2.55),(0.5,0.5,4.1),(0.5,0.5,4.4),(0.5,0.5,4.9),(0.5,0.5,5.1),(0.5,0.5,7.6),(0.5,0.5,7.7),(0.5,0.5,8.2),(0.5,0.5,8.4),(0.5,0.5,8.6),(0.5,0.5,8.8),(0.5,0.5,9.2),(0.5,0.5,9.6),(0.5,0.5,11.5)]) + source=MEDCoupling1SGTUMesh("SourcePrimaire",NORM_SEG2) + source.setCoords(sourceCoo) + source.allocateCells() + for i in xrange(len(sourceCoo)-1): + source.insertNextCell([i,i+1]) + pass + source=source.buildUnstructured() + fsource=MEDCouplingFieldDouble(ON_NODES) ; fsource.setName("field") + fsource.setMesh(source) + arr=DataArrayDouble(len(sourceCoo)) ; arr.iota(0.7) ; arr*=arr + fsource.setArray(arr) + fsource.setNature(ConservativeVolumic) + # + rem=MEDCouplingRemapper() + rem.setIntersectionType(PointLocator) + rem.prepare(source,target,"P1P0") + f2Test=rem.transferField(fsource,-27) + self.assertEqual(f2Test.getName(),fsource.getName()) + self.assertEqual(f2Test.getMesh().getHiddenCppPointer(),target.getHiddenCppPointer()) + expArr=DataArrayDouble([0.49,7.956666666666667,27.29,-27,59.95666666666667,94.09,-27,125.69,202.89,296.09]) + self.assertTrue(f2Test.getArray().isEqual(expArr,1e-12)) + f2Test=rem.reverseTransferField(f2Test,-36) + self.assertEqual(f2Test.getName(),fsource.getName()) + self.assertEqual(f2Test.getMesh().getHiddenCppPointer(),source.getHiddenCppPointer()) + expArr2=DataArrayDouble([0.49,7.956666666666667,7.956666666666667,7.956666666666667,27.29,27.29,59.95666666666667,59.95666666666667,59.95666666666667,94.09,125.69,125.69,202.89,202.89,202.89,202.89,296.09,296.09,-36.]) + self.assertTrue(f2Test.getArray().isEqual(expArr2,1e-12)) + pass def build2DSourceMesh_1(self): sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index 0d5f1216e..e38aaeb45 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -3398,11 +3398,6 @@ std::string MEDFileFieldGlobsReal::getFileName() const return contentNotNull()->getFileName(); } -std::string MEDFileFieldGlobsReal::getFileName2() const -{ - return contentNotNull()->getFileName2(); -} - /*! * Returns a localization object by its name. * \param [in] locName - the name of the localization of interest. @@ -5598,15 +5593,29 @@ void MEDFileAnyTypeField1TS::loadArraysIfNecessary() /*! * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. - * This method does not release arrays set outside the context of a MED file. + * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. + * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss instead. * - * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::loadArraysIfNecessary + * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::loadArraysIfNecessary, MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss */ void MEDFileAnyTypeField1TS::unloadArrays() { contentNotNullBase()->unloadArrays(); } +/*! + * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. + * This method is the symetrical method of MEDFileAnyTypeField1TS::loadArraysIfNecessary. + * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. + * + * \sa MEDFileAnyTypeField1TS::loadArraysIfNecessary + */ +void MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss() +{ + if(!getFileName().empty()) + contentNotNullBase()->unloadArrays(); +} + void MEDFileAnyTypeField1TS::writeLL(med_idt fid) const { int nbComp=getNumberOfComponents(); @@ -6117,7 +6126,7 @@ MEDFileField1TS::MEDFileField1TS() */ MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol) const { - if(getFileName2().empty()) + if(getFileName().empty()) throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); MEDCouplingAutoRefCountObjectPtr arrOut; MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNull()); @@ -6149,7 +6158,7 @@ MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevel(TypeOfField type, int m */ MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtTopLevel(TypeOfField type, int renumPol) const { - if(getFileName2().empty()) + if(getFileName().empty()) throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); MEDCouplingAutoRefCountObjectPtr arrOut; MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNull()); @@ -6242,7 +6251,7 @@ MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, */ MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol) const { - if(getFileName2().empty()) + if(getFileName().empty()) throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); MEDCouplingAutoRefCountObjectPtr arrOut; MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNull()); @@ -6509,7 +6518,7 @@ const MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull() const MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const { - if(getFileName2().empty()) + if(getFileName().empty()) throw INTERP_KERNEL::Exception("MEDFileIntField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); MEDCouplingAutoRefCountObjectPtr arrOut2; MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut2,*contentNotNull()); @@ -6556,7 +6565,7 @@ DataArrayInt *MEDFileIntField1TS::ReturnSafelyDataArrayInt(MEDCouplingAutoRefCou */ MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtTopLevel(TypeOfField type, DataArrayInt* &arrOut, int renumPol) const { - if(getFileName2().empty()) + if(getFileName().empty()) throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); MEDCouplingAutoRefCountObjectPtr arr; MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arr,*contentNotNull()); @@ -6652,7 +6661,7 @@ MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldOnMeshAtLevel(TypeOfField ty */ MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const { - if(getFileName2().empty()) + if(getFileName().empty()) throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); MEDCouplingAutoRefCountObjectPtr arr; MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arr,*contentNotNull()); @@ -8181,15 +8190,29 @@ void MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary() /*! * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. - * This method does not release arrays set outside the context of a MED file. + * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. + * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss instead. * - * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary + * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary, MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss */ void MEDFileAnyTypeFieldMultiTS::unloadArrays() { contentNotNullBase()->unloadArrays(); } +/*! + * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. + * This method is the symetrical method of MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary. + * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. + * + * \sa MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary + */ +void MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss() +{ + if(!getFileName().empty()) + contentNotNullBase()->unloadArrays(); +} + std::string MEDFileAnyTypeFieldMultiTS::simpleRepr() const { std::ostringstream oss; @@ -9639,9 +9662,10 @@ void MEDFileFields::loadArraysIfNecessary() /*! * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. - * This method does not release arrays set outside the context of a MED file. + * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. + * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileFields::unloadArraysWithoutDataLoss instead. * - * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary + * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary, MEDFileFields::unloadArraysWithoutDataLoss */ void MEDFileFields::unloadArrays() { @@ -9653,6 +9677,19 @@ void MEDFileFields::unloadArrays() } } +/*! + * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. + * This method is the symetrical method of MEDFileFields::loadArraysIfNecessary. + * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. + * + * \sa MEDFileFields::loadArraysIfNecessary + */ +void MEDFileFields::unloadArraysWithoutDataLoss() +{ + if(!getFileName().empty()) + unloadArrays(); +} + std::vector MEDFileFields::getPflsReallyUsed() const { std::vector ret; @@ -9888,6 +9925,30 @@ MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldWithName(const std::string& f return getFieldAtPos(getPosFromFieldName(fieldName)); } +/*! + * This method removes, if any, fields in \a this having no time steps. + * If there is one or more than one such field in \a this true is returned and those fields will not be referenced anymore in \a this. + * + * If false is returned \a this does not contain such fields. If false is returned this method can be considered as const. + */ +bool MEDFileFields::removeFieldsWithoutAnyTimeStep() +{ + std::vector > newFields; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); + if(elt) + { + if(elt->getNumberOfTS()>0) + newFields.push_back(*it); + } + } + if(_fields.size()==newFields.size()) + return false; + _fields=newFields; + return true; +} + /*! * This method returns a new object containing part of \a this fields lying on mesh name specified by the input parameter \a meshName. * This method can be seen as a filter applied on \a this, that returns an object containing diff --git a/src/MEDLoader/MEDFileField.hxx b/src/MEDLoader/MEDFileField.hxx index 2d54b1a02..4f993d117 100644 --- a/src/MEDLoader/MEDFileField.hxx +++ b/src/MEDLoader/MEDFileField.hxx @@ -334,7 +334,6 @@ namespace ParaMEDMEM int getNbOfGaussPtPerCell(int locId) const; int getLocalizationId(const std::string& loc) const; std::string getFileName() const { return _file_name; } - std::string getFileName2() const { return _file_name; } const MEDFileFieldLoc& getLocalizationFromId(int locId) const; const MEDFileFieldLoc& getLocalization(const std::string& locName) const; const DataArrayInt *getProfileFromId(int pflId) const; @@ -412,7 +411,6 @@ namespace ParaMEDMEM MEDLOADER_EXPORT int getNbOfGaussPtPerCell(int locId) const; MEDLOADER_EXPORT int getLocalizationId(const std::string& loc) const; MEDLOADER_EXPORT std::string getFileName() const; - MEDLOADER_EXPORT std::string getFileName2() const; MEDLOADER_EXPORT const MEDFileFieldLoc& getLocalizationFromId(int locId) const; MEDLOADER_EXPORT const MEDFileFieldLoc& getLocalization(const std::string& locName) const; MEDLOADER_EXPORT MEDFileFieldLoc& getLocalizationFromId(int locId); @@ -665,6 +663,7 @@ namespace ParaMEDMEM MEDLOADER_EXPORT void loadArrays(); MEDLOADER_EXPORT void loadArraysIfNecessary(); MEDLOADER_EXPORT void unloadArrays(); + MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitComponents() const; MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitDiscretizations() const; MEDLOADER_EXPORT MEDFileAnyTypeField1TS *deepCpy() const; @@ -913,6 +912,7 @@ namespace ParaMEDMEM MEDLOADER_EXPORT void loadArrays(); MEDLOADER_EXPORT void loadArraysIfNecessary(); MEDLOADER_EXPORT void unloadArrays(); + MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; MEDLOADER_EXPORT void writeLL(med_idt fid) const; MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; @@ -1085,6 +1085,7 @@ namespace ParaMEDMEM MEDLOADER_EXPORT void loadArrays(); MEDLOADER_EXPORT void loadArraysIfNecessary(); MEDLOADER_EXPORT void unloadArrays(); + MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); MEDLOADER_EXPORT int getNumberOfFields() const; MEDLOADER_EXPORT std::vector< std::pair > getCommonIterations(bool& areThereSomeForgottenTS) const; MEDLOADER_EXPORT std::vector getFieldsNames() const; @@ -1100,6 +1101,7 @@ namespace ParaMEDMEM MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *getFieldAtPos(int i) const; MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *getFieldWithName(const std::string& fieldName) const; MEDLOADER_EXPORT MEDFileFields *buildSubPart(const int *startIds, const int *endIds) const; + MEDLOADER_EXPORT bool removeFieldsWithoutAnyTimeStep(); MEDLOADER_EXPORT MEDFileFields *partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const; MEDLOADER_EXPORT MEDFileFields *partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const; MEDLOADER_EXPORT MEDFileFields *partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const; diff --git a/src/MEDLoader/MEDFileFieldOverView.cxx b/src/MEDLoader/MEDFileFieldOverView.cxx index 241cd422e..94c959bf3 100644 --- a/src/MEDLoader/MEDFileFieldOverView.cxx +++ b/src/MEDLoader/MEDFileFieldOverView.cxx @@ -29,6 +29,8 @@ using namespace ParaMEDMEM; const unsigned char MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH]= {1,3,21,5,9,7,22,34,23,28,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,36,4}; +const unsigned char MEDMeshMultiLev::HEXA27_PERM_ARRAY[27]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26}; + const char MEDFileField1TSStructItem2::NEWLY_CREATED_PFL_NAME[]="???"; MEDFileMeshStruct *MEDFileMeshStruct::New(const MEDFileMesh *mesh) @@ -945,12 +947,25 @@ bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte * throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !"); if(scur) { - int nnpc(scur->getNumberOfNodesPerCell()); - for(int i=0;igetCellModelEnum()!=INTERP_KERNEL::NORM_HEXA27) + { + int nnpc(scur->getNumberOfNodesPerCell()); + for(int i=0;iisNodeFamilyFieldReading()) { + int nbNodes(getNumberOfNodes()); _fam_nodes=DataArrayInt::New(); - _fam_nodes->alloc(nbOfElt,1); + _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line. + if(nbNodes!=nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378... + _fam_nodes->fillWithZero(); MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()); } } diff --git a/src/MEDLoader/MEDFileMeshLL.cxx b/src/MEDLoader/MEDFileMeshLL.cxx index 3bc21de7b..9159f8a34 100644 --- a/src/MEDLoader/MEDFileMeshLL.cxx +++ b/src/MEDLoader/MEDFileMeshLL.cxx @@ -250,6 +250,8 @@ void MEDFileUMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int int Mdim; ParaMEDMEM::MEDCouplingMeshType meshType; std::vector infosOnComp=getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim); + if(nstep==0) + return ; if(meshType!=UNSTRUCTURED) throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected an unstructured one whereas in file it is not an unstructured !"); _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); diff --git a/src/MEDLoader/MEDFileParameter.cxx b/src/MEDLoader/MEDFileParameter.cxx index 38559d7ae..c32f667b4 100644 --- a/src/MEDLoader/MEDFileParameter.cxx +++ b/src/MEDLoader/MEDFileParameter.cxx @@ -606,7 +606,7 @@ int MEDFileParameterMultiTS::getPosOfTimeStep(int iteration, int order) const const MEDFileParameter1TS *elt(*it); if(elt) { - if(elt->getIteration()==iteration && elt->getOrder()) + if(elt->getIteration()==iteration && elt->getOrder()==order) return ret; else oss << "(" << elt->getIteration() << "," << elt->getOrder() << "), "; @@ -666,6 +666,11 @@ void MEDFileParameterMultiTS::eraseTimeStepIds(const int *startIds, const int *e _param_per_ts=paramPerTs; } +int MEDFileParameterMultiTS::getNumberOfTS() const +{ + return (int) getIterations().size(); +} + std::vector< std::pair > MEDFileParameterMultiTS::getIterations() const { std::vector< std::pair > ret; diff --git a/src/MEDLoader/MEDFileParameter.hxx b/src/MEDLoader/MEDFileParameter.hxx index 1bc97c27f..9507c845a 100644 --- a/src/MEDLoader/MEDFileParameter.hxx +++ b/src/MEDLoader/MEDFileParameter.hxx @@ -138,6 +138,7 @@ namespace ParaMEDMEM MEDLOADER_EXPORT int getPosGivenTime(double time, double eps=1e-8) const; MEDLOADER_EXPORT MEDFileParameter1TS *getTimeStepAtPos(int posId) const; MEDLOADER_EXPORT void eraseTimeStepIds(const int *startIds, const int *endIds); + MEDLOADER_EXPORT int getNumberOfTS() const; MEDLOADER_EXPORT std::vector< std::pair > getIterations() const; MEDLOADER_EXPORT std::vector< std::pair > getTimeSteps(std::vector& ret1) const; MEDLOADER_EXPORT void simpleRepr2(int bkOffset, std::ostream& oss) const; diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index 594c74967..b6e033ce8 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -1026,7 +1026,7 @@ namespace ParaMEDMEM { if(PyInt_Check(obj)) { - MEDFileMesh *ret=self->getMeshAtPos((int)PyInt_AS_LONG(obj)); + MEDFileMesh *ret=self->getMeshAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfMeshes())); if(ret) ret->incrRef(); return ret; @@ -1226,6 +1226,7 @@ namespace ParaMEDMEM void loadArrays() throw(INTERP_KERNEL::Exception); void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); void unloadArrays() throw(INTERP_KERNEL::Exception); + void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); int getDimension() const throw(INTERP_KERNEL::Exception); int getIteration() const throw(INTERP_KERNEL::Exception); int getOrder() const throw(INTERP_KERNEL::Exception); @@ -1642,6 +1643,7 @@ namespace ParaMEDMEM void loadArrays() throw(INTERP_KERNEL::Exception); void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); void unloadArrays() throw(INTERP_KERNEL::Exception); + void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); // virtual MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception); MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); @@ -1808,12 +1810,8 @@ namespace ParaMEDMEM { Py_ssize_t strt=2,stp=2,step=2; PySliceObject *oC=reinterpret_cast(elts); - if(PySlice_GetIndices(oC,self->getNumberOfTS(),&strt,&stp,&step)==0) - { - self->eraseTimeStepIds2(strt,stp,step); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS.__delitem__ : error in input slice !"); + GetIndicesOfSlice(oC,self->getNumberOfTS(),&strt,&stp,&step,"MEDFileAnyTypeFieldMultiTS.__delitem__ : error in input slice !"); + self->eraseTimeStepIds2(strt,stp,step); } else { @@ -1878,10 +1876,8 @@ namespace ParaMEDMEM { Py_ssize_t strt=2,stp=2,step=2; PySliceObject *oC=reinterpret_cast(elt0); - if(PySlice_GetIndices(oC,self->getNumberOfTS(),&strt,&stp,&step)==0) - return convertMEDFileFieldMultiTS(self->buildSubPartSlice(strt,stp,step),SWIG_POINTER_OWN | 0); - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS.__getitem__ : error in input slice !"); + GetIndicesOfSlice(oC,self->getNumberOfTS(),&strt,&stp,&step,"MEDFileAnyTypeFieldMultiTS.__getitem__ : error in input slice !"); + return convertMEDFileFieldMultiTS(self->buildSubPartSlice(strt,stp,step),SWIG_POINTER_OWN | 0); } else return convertMEDFileField1TS(self->getTimeStepAtPos(MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(self,elt0)),SWIG_POINTER_OWN | 0); @@ -2226,6 +2222,7 @@ namespace ParaMEDMEM void loadArrays() throw(INTERP_KERNEL::Exception); void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); void unloadArrays() throw(INTERP_KERNEL::Exception); + void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); int getNumberOfFields() const; std::vector getFieldsNames() const throw(INTERP_KERNEL::Exception); @@ -2239,6 +2236,7 @@ namespace ParaMEDMEM MEDFileAnyTypeFieldMultiTS *getFieldWithName(const std::string& fieldName) const throw(INTERP_KERNEL::Exception); MEDFileFields *partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const throw(INTERP_KERNEL::Exception); void destroyFieldAtPos(int i) throw(INTERP_KERNEL::Exception); + bool removeFieldsWithoutAnyTimeStep() throw(INTERP_KERNEL::Exception); %extend { MEDFileFields() @@ -2374,10 +2372,8 @@ namespace ParaMEDMEM { Py_ssize_t strt=2,stp=2,step=2; PySliceObject *oC=reinterpret_cast(elts); - if(PySlice_GetIndices(oC,self->getNumberOfFields(),&strt,&stp,&step)==0) - self->destroyFieldsAtPos2(strt,stp,step); - else - throw INTERP_KERNEL::Exception("MEDFileFields.__delitem__ : error in input slice !"); + GetIndicesOfSlice(oC,self->getNumberOfFields(),&strt,&stp,&step,"MEDFileFields.__delitem__ : error in input slice !"); + self->destroyFieldsAtPos2(strt,stp,step); } else { @@ -2494,6 +2490,7 @@ namespace ParaMEDMEM double getDoubleValue(int iteration, int order) const throw(INTERP_KERNEL::Exception); int getPosOfTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); int getPosGivenTime(double time, double eps=1e-8) const throw(INTERP_KERNEL::Exception); + int getNumberOfTS() const throw(INTERP_KERNEL::Exception); %extend { MEDFileParameterMultiTS() @@ -2564,7 +2561,7 @@ namespace ParaMEDMEM { if(elt0 && PyInt_Check(elt0)) {//fmts[3] - int pos=PyInt_AS_LONG(elt0); + int pos=InterpreteNegativeInt(PyInt_AS_LONG(elt0),self->getNumberOfTS()); return pos; } else if(elt0 && PyTuple_Check(elt0)) @@ -2708,7 +2705,7 @@ namespace ParaMEDMEM { if(PyInt_Check(obj)) { - MEDFileParameterMultiTS *ret=self->getParamAtPos((int)PyInt_AS_LONG(obj)); + MEDFileParameterMultiTS *ret=self->getParamAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfParams())); if(ret) ret->incrRef(); return ret; diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py index 76318a2c6..308145261 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ b/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -3583,6 +3583,69 @@ class MEDLoaderTest(unittest.TestCase): self.assertEqual(mm.getMeshAtLevel(0).getName(),"abc") pass + def testMEDFileFieldsUnloadArraysWithoutDataLoss1(self): + fileName="Pyfile80.med" + m=MEDCouplingCMesh() ; m.setName("cmesh") + arr=DataArrayDouble(6) ; arr.iota() + m.setCoords(arr,arr) + nbCells=m.getNumberOfCells() + self.assertEqual(25,nbCells) + f=MEDCouplingFieldDouble(ON_CELLS) + f.setName("FieldOnCell") ; f.setMesh(m) + arr=DataArrayDouble(nbCells) ; arr.iota() + mm=MEDFileCMesh() + mm.setMesh(m) + # + fmts=MEDFileFieldMultiTS() + # + for i in xrange(nbCells): + t=(float(i)+0.1,i+1,-i-2) + f.setTime(*t) + arr2=DataArrayDouble(nbCells) + perm=DataArrayInt(nbCells) ; perm.iota(i) ; perm%=nbCells + arr2[perm]=arr + f.setArray(arr2) + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f) + fmts.pushBackTimeStep(f1ts) + pass + fmts.unloadArraysWithoutDataLoss() + self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + fs=MEDFileFields() ; fs.pushField(fmts) + self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + fs.unloadArraysWithoutDataLoss() + self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + f1ts=fs[0][0] + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + f1ts.unloadArraysWithoutDataLoss() + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + mm.write(fileName,2) + fs.write(fileName,0) + del m,fmts,mm,f,f1ts + ## + mm=MEDFileMesh.New(fileName) + fmts=MEDFileFieldMultiTS(fileName) + self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + fmts.unloadArraysWithoutDataLoss() + self.assertTrue(not fmts[0].getUndergroundDataArray().isAllocated()) + fmts.loadArraysIfNecessary() + self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + del mm,fmts + fs=MEDFileFields(fileName) + self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + fs.unloadArraysWithoutDataLoss() + self.assertTrue(not fs[0][0].getUndergroundDataArray().isAllocated()) + fs.loadArraysIfNecessary() + self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + del fs + f1ts=MEDFileField1TS(fileName) + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + f1ts.unloadArraysWithoutDataLoss() + self.assertTrue(not f1ts.getUndergroundDataArray().isAllocated()) + f1ts.loadArraysIfNecessary() + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + pass + pass unittest.main() diff --git a/src/MEDLoader/Swig/MEDLoaderTest4.py b/src/MEDLoader/Swig/MEDLoaderTest4.py index 164269087..75147a659 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest4.py +++ b/src/MEDLoader/Swig/MEDLoaderTest4.py @@ -151,6 +151,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) # False is important to not read the values + fields.removeFieldsWithoutAnyTimeStep() refMem=fields.getHeapMemorySize() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] @@ -362,6 +363,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -523,6 +525,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -773,6 +776,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -900,6 +904,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -1061,6 +1066,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -1265,6 +1271,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -1459,6 +1466,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -1602,6 +1610,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -1730,6 +1739,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -1828,6 +1838,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -1918,6 +1929,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -2030,6 +2042,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -2181,6 +2194,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -2338,6 +2352,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -2525,6 +2540,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -2596,6 +2612,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -2707,6 +2724,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -2872,6 +2890,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -3051,6 +3070,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -3247,6 +3267,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -3354,6 +3375,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -3454,6 +3476,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -3557,6 +3580,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) # false is absolutely necessary for the test + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -3766,6 +3790,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -3876,6 +3901,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() self.assertEqual(fields[0].getMeshName(),"mesh") self.assertEqual(fields[1].getMeshName(),"mesh") fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] @@ -4017,6 +4043,7 @@ class MEDLoaderTest4(unittest.TestCase): ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values ms=MEDFileMeshes(fname) fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] allFMTSLeavesToDisplay=[] for fields in fields_per_mesh: @@ -4123,6 +4150,85 @@ class MEDLoaderTest4(unittest.TestCase): vExp=DataArrayDouble([-1.1,-3.1,5,4,3,2,1,0]) self.assertTrue(v.isEqual(vExp,1e-12)) pass + + def test29(self): + """ This test focused on HEXA27 cell for which the MED numbering is not equal to the VTK numbering. So here the HEXA27 cell is those in MED file documentation (reference element). + """ + fname="ForMEDReader29.med" + coo=DataArrayDouble([[0.,2.,2.],[0.,0.,2.],[2.,0.,2.],[2.,2.,2.],[0.,2.,0.],[0.,0.,0.],[2.,0.,0.],[2.,2.,0.], [0.,1.,2.],[1.,0.,2.],[2.,1.,2.],[1.,2.,2.], [0.,1.,0.],[1.,0.,0.],[2.,1.,0.],[1.,2.,0.], [0.,2.,1.],[0.,0.,1.],[2.,0.,1.],[2.,2.,1.], [1.,1.,2.], [0.,1.,1.],[1.,0.,1.],[2.,1.,1.],[1.,2.,1.], [1.,1.,0.], [1.,1.,1.]]) + m=MEDCouplingUMesh("mesh",3) ; m.setCoords(coo) + m.allocateCells() + # MED = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26] + # VTK = [0,1,2,3,4,5,6,7, 8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26] + m.insertNextCell(NORM_HEXA27,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]) + fCell=MEDCouplingFieldDouble(ON_CELLS) ; fCell.setName("fCell") + arrCell=DataArrayDouble([7.]) ; arrCell.setInfoOnComponent(0,"smth") ; fCell.setArray(arrCell) + fCell.setMesh(m) + MEDLoader.WriteField(fname,fCell,True) + refCoo=[-1.,-1.,-1.,-1.,1.,-1.,1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,-1.,1.,1.,1.,1.,1.,1.,-1.,1.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.] + weights=[0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.7023319615912209,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571] + gCoords=[-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,0.0,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.0,0.0,0.0,0.0,0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,0.0,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483] + fGauss=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fGauss.setName("fGauss") + fGauss.setMesh(m) + fGauss.setGaussLocalizationOnType(NORM_HEXA27,refCoo,gCoords,weights) + arrGauss=DataArrayDouble(fGauss.getNumberOfTuplesExpected()) ; arrGauss.setInfoOnComponent(0,"gaussc") ; arrGauss.iota() + fGauss.setArray(arrGauss) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,fGauss) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + allFMTSLeavesToDisplay2+=fmts.splitDiscretizations() + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(a0.isEqual(coo,1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([29]))) + self.assertTrue(a2.isEqual(DataArrayInt([0]))) + # the connectivity must be not a iota as declared in m.insertNextCell + self.assertTrue(a3.isEqual(DataArrayInt([27,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26])))# the test is on this line to check that connectivity has been processed for HEXA27 + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) + self.assertEqual(ffCell.getName(),"fCell") + self.assertTrue(v.isEqual(arrCell,1e-12)) ; self.assertTrue(v.isEqualWithoutConsideringStr(DataArrayDouble([7.]),1e-12)) ; self.assertEqual(v.getInfoOnComponents(),["smth"]) + del ffCell + # + ffGauss=allFMTSLeavesPerCommonSupport1[0][0][1][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffGauss,mst) + ffGauss.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffGauss.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffGauss.getUndergroundDataArray().getHiddenCppPointer()) + self.assertEqual(ffGauss.getName(),"fGauss") + self.assertTrue(v.isEqual(arrGauss,1e-12)) ; self.assertTrue(v.isEqualWithoutConsideringStr(DataArrayDouble(range(27)),1e-12)) ; self.assertEqual(v.getInfoOnComponents(),["gaussc"]) + ffGauss=allFMTSLeavesPerCommonSupport1[0][0][1][0] + pass + pass unittest.main() diff --git a/src/MEDLoader/Swig/MEDLoaderTypemaps.i b/src/MEDLoader/Swig/MEDLoaderTypemaps.i index 44b2c7791..941202766 100644 --- a/src/MEDLoader/Swig/MEDLoaderTypemaps.i +++ b/src/MEDLoader/Swig/MEDLoaderTypemaps.i @@ -310,7 +310,7 @@ int MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(const MEDFileAnyTypeFieldMultiTS { if(elt0 && PyInt_Check(elt0)) {//fmts[3] - return PyInt_AS_LONG(elt0); + return InterpreteNegativeInt(PyInt_AS_LONG(elt0),self->getNumberOfTS()); } else if(elt0 && PyTuple_Check(elt0)) { @@ -347,7 +347,7 @@ int MEDFileFieldsgetitemSingleTS__(const MEDFileFields *self, PyObject *obj) thr { if(PyInt_Check(obj)) { - return (int)PyInt_AS_LONG(obj); + return InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfFields()); } else if(PyString_Check(obj)) { diff --git a/src/ParaMEDMEM/InterpolationMatrix.cxx b/src/ParaMEDMEM/InterpolationMatrix.cxx index fc122596e..352566534 100644 --- a/src/ParaMEDMEM/InterpolationMatrix.cxx +++ b/src/ParaMEDMEM/InterpolationMatrix.cxx @@ -181,6 +181,17 @@ namespace ParaMEDMEM target_wrapper.releaseTempArrays(); source_wrapper.releaseTempArrays(); } + else if ( distant_support.getMeshDimension() == 3 + && _source_support->getMeshDimension() == 1 + && distant_support.getSpaceDimension() == 3 && _source_support->getSpaceDimension() == 3) + { + MEDCouplingNormalizedUnstructuredMesh<3,3> target_wrapper(distant_supportC); + MEDCouplingNormalizedUnstructuredMesh<3,3> source_wrapper(source_supportC); + INTERP_KERNEL::Interpolation3D interpolator (*this); + interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod); + target_wrapper.releaseTempArrays(); + source_wrapper.releaseTempArrays(); + } else if (distant_support.getMeshDimension() != _source_support->getMeshDimension()) { throw INTERP_KERNEL::Exception("local and distant meshes do not have the same space and mesh dimensions"); diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx b/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx index 8f83469ae..6c3f6f566 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx @@ -72,6 +72,7 @@ class ParaMEDMEMTest : public CppUnit::TestFixture CPPUNIT_TEST(testGauthier1); CPPUNIT_TEST(testGauthier2); CPPUNIT_TEST(testGauthier3); + CPPUNIT_TEST(testGauthier4); CPPUNIT_TEST(testFabienAPI1); CPPUNIT_TEST(testFabienAPI2); CPPUNIT_TEST(testMEDLoaderRead1); @@ -126,6 +127,7 @@ public: void testGauthier1(); void testGauthier2(); void testGauthier3(); + void testGauthier4(); void testFabienAPI1(); void testFabienAPI2(); // diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx index d786e7b1d..399b77504 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx @@ -20,17 +20,22 @@ #include "ParaMEDMEMTest.hxx" #include -#include #include "CommInterface.hxx" #include "ProcessorGroup.hxx" #include "MPIProcessorGroup.hxx" #include "DEC.hxx" #include "InterpKernelDEC.hxx" +#include "ICoCoTrioField.hxx" +#include "MEDCouplingUMesh.hxx" +#include "ParaMESH.hxx" +#include "ParaFIELD.hxx" +#include "ComponentTopology.hxx" + #include #include -#include "ICoCoTrioField.hxx" #include #include +#include #include using namespace std; @@ -585,3 +590,158 @@ void ParaMEDMEMTest::testGauthier3() } } } + +/*! + * This test is the parallel version of MEDCouplingBasicsTest.test3D1DOnP1P0_1 test. + */ +void ParaMEDMEMTest::testGauthier4() +{ + // + const double sourceCoords[19*3]={0.5,0.5,0.1,0.5,0.5,1.2,0.5,0.5,1.6,0.5,0.5,1.8,0.5,0.5,2.43,0.5,0.5,2.55,0.5,0.5,4.1,0.5,0.5,4.4,0.5,0.5,4.9,0.5,0.5,5.1,0.5,0.5,7.6,0.5,0.5,7.7,0.5,0.5,8.2,0.5,0.5,8.4,0.5,0.5,8.6,0.5,0.5,8.8,0.5,0.5,9.2,0.5,0.5,9.6,0.5,0.5,11.5}; + const int sourceConn[18*2]={0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18}; + const double sourceVals[19]={0.49,2.8899999999999997,7.29,13.69,22.09,32.49,44.89,59.29,75.69,94.09, 114.49,136.89,161.29,187.69,216.09,246.49,278.89,313.29,349.69}; + const double targetCoords0[20*3]={0.,0.,0.,1.,0.,0.,0.,1.,0.,1.,1.,0.,0.,0.,1.,1.,0.,1.,0.,1.,1.,1.,1.,1.,0.,0.,2.,1.,0.,2.,0.,1.,2.,1.,1.,2.,0.,0.,3.,1.,0.,3.,0.,1.,3.,1.,1.,3.,0.,0.,4.,1.,0.,4.,0.,1.,4.,1.,1.,4.}; + const int targetConn0[8*4]={1,0,2,3,5,4,6,7,5,4,6,7,9,8,10,11,9,8,10,11,13,12,14,15,13,12,14,15,17,16,18,19}; + const double targetCoords1[28*3]={0.,0.,4.,1.,0.,4.,0.,1.,4.,1.,1.,4.,0.,0.,5.,1.,0.,5.,0.,1.,5.,1.,1.,5.,0.,0.,6.,1.,0.,6.,0.,1.,6.,1.,1.,6.,0.,0.,7.,1.,0.,7.,0.,1.,7.,1.,1.,7.,0.,0.,8.,1.,0.,8.,0.,1.,8.,1.,1.,8.,0.,0.,9.,1.,0.,9.,0.,1.,9.,1.,1.,9.,0.,0.,10.,1.,0.,10.,0.,1.,10.,1.,1.,10.}; + const int targetConn1[8*6]={1,0,2,3,5,4,6,7,5,4,6,7,9,8,10,11,9,8,10,11,13,12,14,15,13,12,14,15,17,16,18,19,17,16,18,19,21,20,22,23,21,20,22,23,25,24,26,27}; + // + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + // + if(size!=3) + return ; + int nproc_source = 1; + set self_procs; + set procs_source; + set procs_target; + + for (int i=0; icontainsMyRank()) + { + std::ostringstream stream; stream << "sourcemesh2D proc " << rank; + mesh=MEDCouplingUMesh::New(stream.str().c_str(),1); + mesh->allocateCells(); + for(int i=0;i<18;i++) + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+2*i); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(19,3); + std::copy(sourceCoords,sourceCoords+19*3,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*source_group,"source mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh,comptopo); + double *value=parafield->getField()->getArray()->getPointer(); + std::copy(sourceVals,sourceVals+19,value); + } + else + { + if(rank==1) + { + std::ostringstream stream; stream << "targetmesh2D proc " << rank-nproc_source; + mesh=MEDCouplingUMesh::New(stream.str().c_str(),3); + mesh->allocateCells(); + for(int i=0;i<4;i++) + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn0+8*i); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(20,3); + std::copy(targetCoords0,targetCoords0+20*3,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH (mesh,*target_group,"target mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + } + else if(rank==2) + { + std::ostringstream stream; stream << "targetmesh2D proc " << rank-nproc_source; + mesh=MEDCouplingUMesh::New(stream.str().c_str(),3); + mesh->allocateCells(); + for(int i=0;i<6;i++) + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn1+8*i); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(28,3); + std::copy(targetCoords1,targetCoords1+28*3,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH (mesh,*target_group,"target mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + } + } + //test 1 - primaire -> secondaire + ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); + dec.setIntersectionType(INTERP_KERNEL::PointLocator); + parafield->getField()->setNature(ConservativeVolumic);//very important + if (source_group->containsMyRank()) + { + dec.setMethod("P1"); + dec.attachLocalField(parafield); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.sendData(); + } + else + { + dec.setMethod("P0"); + dec.attachLocalField(parafield); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.recvData(); + const double *res(parafield->getField()->getArray()->getConstPointer()); + if(rank==1) + { + const double expected0[4]={0.49,7.956666666666667,27.29,0.}; + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected0[i],res[i],1e-13); + } + else + { + const double expected1[6]={59.95666666666667,94.09,0.,125.69,202.89,296.09}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],res[i],1e-13); + } + } + MPI_Barrier(MPI_COMM_WORLD); + if (source_group->containsMyRank()) + { + dec.recvData(); + const double expected2[19]={0.49,7.956666666666667,7.956666666666667,7.956666666666667,27.29,27.29,59.95666666666667,59.95666666666667,59.95666666666667,94.09,125.69,125.69,202.89,202.89,202.89,202.89,296.09,296.09,0.}; + const double *res(parafield->getField()->getArray()->getConstPointer()); + for(int i=0;i<19;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],res[i],1e-13); + } + else + { + dec.sendData(); + } + delete parafield; + mesh->decrRef(); + delete paramesh; + delete self_group; + delete target_group; + delete source_group; + // + MPI_Barrier(MPI_COMM_WORLD); +}