#include <functional>
#include <algorithm>
+#include <sstream>
#include <numeric>
using namespace ParaMEDMEM;
#include <algorithm>
#include <functional>
#include <iterator>
+#include <sstream>
#include <cmath>
#include <list>
#include <set>
#include <set>
#include <list>
#include <limits>
+#include <sstream>
#include <algorithm>
#include <functional>
#include <sstream>
#include <limits>
+#include <algorithm>
#include <functional>
using namespace ParaMEDMEM;
#include "MEDCouplingFieldDouble.hxx"
#include "MEDCouplingFieldDiscretization.hxx"
+#include <sstream>
+
using namespace ParaMEDMEM;
MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception)
using namespace ParaMEDMEM;
+template<int SPACEDIM>
+void DataArrayDouble::findCommonTuplesAlg(std::vector<double>& bbox,
+ int nbNodes, int limitNodeId, double prec, std::vector<int>& c, std::vector<int>& cI) const
+{
+ const double *coordsPtr=getConstPointer();
+ BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbNodes,-prec);
+ double bb[2*SPACEDIM];
+ double prec2=prec*prec;
+ std::vector<bool> isDone(nbNodes);
+ for(int i=0;i<nbNodes;i++)
+ {
+ if(!isDone[i])
+ {
+ for(int j=0;j<SPACEDIM;j++)
+ {
+ bb[2*j]=coordsPtr[SPACEDIM*i+j];
+ bb[2*j+1]=coordsPtr[SPACEDIM*i+j];
+ }
+ std::vector<int> intersectingElems;
+ myTree.getIntersectingElems(bb,intersectingElems);
+ if(intersectingElems.size()>1)
+ {
+ std::vector<int> commonNodes;
+ for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
+ if(*it!=i)
+ if(*it>=limitNodeId)
+ if(INTERP_KERNEL::distance2<SPACEDIM>(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it))<prec2)
+ {
+ commonNodes.push_back(*it);
+ isDone[*it]=true;
+ }
+ if(!commonNodes.empty())
+ {
+ cI.push_back(cI.back()+commonNodes.size()+1);
+ c.push_back(i);
+ c.insert(c.end(),commonNodes.begin(),commonNodes.end());
+ }
+ }
+ }
+ }
+}
+
void DataArray::setName(const char *name)
{
_name=name;
copyPartOfStringInfoFrom2(compIds,*other);
}
+/*!
+ * This methods searches for each tuple if there are any tuples in 'this' that are less far than 'prec' from n1. if any, these tuples are stored in out params
+ * comm and commIndex. The distance is computed using norm2. This method expects that 'this' is allocated and that the number of components is in [1,2,3].
+ * If not an exception will be thrown.
+ * This method is typically used by MEDCouplingPointSet::findCommonNodes and MEDCouplingUMesh::mergeNodes.
+ * @param limitNodeId is the limit node id. All nodes which id is strictly lower than 'limitNodeId' will not be merged each other.
+ * @param comm out parameter (not inout)
+ * @param commIndex out parameter (not inout)
+ */
+void DataArrayDouble::findCommonTuples(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
+{
+ comm=DataArrayInt::New();
+ commIndex=DataArrayInt::New();
+ //
+ checkAllocated();
+ int nbOfTuples=getNumberOfTuples();
+ int nbOfCompo=getNumberOfComponents();
+ std::vector<double> bbox(2*nbOfTuples*nbOfCompo);
+ const double *coordsPtr=getConstPointer();
+ for(int i=0;i<nbOfTuples;i++)
+ {
+ for(int j=0;j<nbOfCompo;j++)
+ {
+ bbox[2*nbOfCompo*i+2*j]=coordsPtr[nbOfCompo*i+j];
+ bbox[2*nbOfCompo*i+2*j+1]=coordsPtr[nbOfCompo*i+j];
+ }
+ }
+ //
+ std::vector<int> c,cI(1);
+ switch(nbOfCompo)
+ {
+ case 3:
+ findCommonTuplesAlg<3>(bbox,nbOfTuples,limitNodeId,prec,c,cI);
+ break;
+ case 2:
+ findCommonTuplesAlg<2>(bbox,nbOfTuples,limitNodeId,prec,c,cI);
+ break;
+ case 1:
+ findCommonTuplesAlg<1>(bbox,nbOfTuples,limitNodeId,prec,c,cI);
+ break;
+ default:
+ throw INTERP_KERNEL::Exception("Unexpected spacedim of coords. Must be 1, 2 or 3.");
+ }
+ commIndex->alloc(cI.size(),1);
+ std::copy(cI.begin(),cI.end(),commIndex->getPointer());
+ comm->alloc(cI.back(),1);
+ std::copy(c.begin(),c.end(),comm->getPointer());
+}
+
void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
{
copyPartOfStringInfoFrom2(compoIds,*a);
MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT void meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception);
+ MEDCOUPLING_EXPORT void findCommonTuples(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const;
MEDCOUPLING_EXPORT bool resizeForUnserialization(const std::vector<int>& tinyInfoI);
MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS);
+ protected:
+ template<int SPACEDIM>
+ void findCommonTuplesAlg(std::vector<double>& bbox,
+ int nbNodes, int limitNodeId, double prec, std::vector<int>& c, std::vector<int>& cI) const;
private:
DataArrayDouble() { }
private:
#include "MEDCouplingMemArray.hxx"
#include "NormalizedUnstructuredMesh.hxx"
#include "InterpKernelException.hxx"
+#include "InterpolationUtils.hxx"
+#include "BBTree.txx"
#include <sstream>
#include <algorithm>
#include "MEDCouplingMesh.hxx"
#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include <sstream>
+#include <algorithm>
+
using namespace ParaMEDMEM;
MEDCouplingMultiFields *MEDCouplingMultiFields::New(const std::vector<MEDCouplingFieldDouble *>& fs) throw(INTERP_KERNEL::Exception)
* @param areNodesMerged output parameter that states if some nodes have been "merged" in returned array
* @param newNbOfNodes output parameter too this is the maximal id in returned array to avoid to recompute it.
*/
-DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(int limitNodeId, double precision, bool& areNodesMerged, int& newNbOfNodes) const
+DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const
{
DataArrayInt *comm,*commI;
- findCommonNodes(limitNodeId,precision,comm,commI);
+ findCommonNodes(precision,limitNodeId,comm,commI);
int oldNbOfNodes=getNumberOfNodes();
DataArrayInt *ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes);
areNodesMerged=(oldNbOfNodes!=newNbOfNodes);
}
/*!
- * This methods searches for each node n1 nodes in _coords that are less far than 'prec' from n1. if any these nodes are stored in params
+ * This methods searches for each node if there are any nodes in _coords that are less far than 'prec' from n1. if any, these nodes are stored in out params
* comm and commIndex.
* @param limitNodeId is the limit node id. All nodes which id is strictly lower than 'limitNodeId' will not be merged each other.
* @param comm out parameter (not inout)
* @param commIndex out parameter (not inout)
*/
-void MEDCouplingPointSet::findCommonNodes(int limitNodeId, double prec, DataArrayInt *&comm, DataArrayInt *&commIndex) const
+void MEDCouplingPointSet::findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
{
- comm=DataArrayInt::New();
- commIndex=DataArrayInt::New();
- //
- int nbNodesOld=getNumberOfNodes();
- int spaceDim=getSpaceDimension();
- std::vector<double> bbox(2*nbNodesOld*spaceDim);
- const double *coordsPtr=_coords->getConstPointer();
- for(int i=0;i<nbNodesOld;i++)
- {
- for(int j=0;j<spaceDim;j++)
- {
- bbox[2*spaceDim*i+2*j]=coordsPtr[spaceDim*i+j];
- bbox[2*spaceDim*i+2*j+1]=coordsPtr[spaceDim*i+j];
- }
- }
- //
- std::vector<int> c,cI(1);
- switch(spaceDim)
- {
- case 3:
- findCommonNodesAlg<3>(bbox,nbNodesOld,limitNodeId,prec,c,cI);
- break;
- case 2:
- findCommonNodesAlg<2>(bbox,nbNodesOld,limitNodeId,prec,c,cI);
- break;
- case 1:
- findCommonNodesAlg<1>(bbox,nbNodesOld,limitNodeId,prec,c,cI);
- break;
- default:
- throw INTERP_KERNEL::Exception("Unexpected spacedim of coords. Must be 1, 2 or 3.");
- }
- commIndex->alloc(cI.size(),1);
- std::copy(cI.begin(),cI.end(),commIndex->getPointer());
- comm->alloc(cI.back(),1);
- std::copy(c.begin(),c.end(),comm->getPointer());
+ if(!_coords)
+ throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findCommonNodes : no coords specified !");
+ _coords->findCommonTuples(prec,limitNodeId,comm,commIndex);
}
std::vector<int> MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception)
bool areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const;
virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0;
virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0;
- DataArrayInt *buildPermArrayForMergeNode(int limitNodeId, double precision, bool& areNodesMerged, int& newNbOfNodes) const;
+ DataArrayInt *buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const;
std::vector<int> getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception);
void getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, std::vector<int>& c, std::vector<int>& cI) const throw(INTERP_KERNEL::Exception);
- void findCommonNodes(int limitNodeId, double prec, DataArrayInt *&comm, DataArrayInt *&commIndex) const;
+ void findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const;
DataArrayInt *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex,
int& newNbOfNodes) const;
void getBoundingBox(double *bbox) const;
void project2DCellOnXY(const int *startConn, const int *endConn, std::vector<double>& res) const;
static bool isButterfly2DCell(const std::vector<double>& res, bool isQuad);
template<int SPACEDIM>
- void findCommonNodesAlg(std::vector<double>& bbox,
- int nbNodes, int limitNodeId, double prec, std::vector<int>& c, std::vector<int>& cI) const;
- template<int SPACEDIM>
void findNodeIdsNearPointAlg(std::vector<double>& bbox, const double *pos, int nbNodes, double eps,
std::vector<int>& c, std::vector<int>& cI) const;
protected:
namespace ParaMEDMEM
{
- template<int SPACEDIM>
- void MEDCouplingPointSet::findCommonNodesAlg(std::vector<double>& bbox,
- int nbNodes, int limitNodeId, double prec,
- std::vector<int>& c, std::vector<int>& cI) const
- {
- const double *coordsPtr=_coords->getConstPointer();
- BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbNodes,-prec);
- double bb[2*SPACEDIM];
- double prec2=prec*prec;
- std::vector<bool> isDone(nbNodes);
- for(int i=0;i<nbNodes;i++)
- {
- if(!isDone[i])
- {
- for(int j=0;j<SPACEDIM;j++)
- {
- bb[2*j]=coordsPtr[SPACEDIM*i+j];
- bb[2*j+1]=coordsPtr[SPACEDIM*i+j];
- }
- std::vector<int> intersectingElems;
- myTree.getIntersectingElems(bb,intersectingElems);
- if(intersectingElems.size()>1)
- {
- std::vector<int> commonNodes;
- for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
- if(*it!=i)
- if(*it>=limitNodeId)
- if(INTERP_KERNEL::distance2<SPACEDIM>(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it))<prec2)
- {
- commonNodes.push_back(*it);
- isDone[*it]=true;
- }
- if(!commonNodes.empty())
- {
- cI.push_back(cI.back()+commonNodes.size()+1);
- c.push_back(i);
- c.insert(c.end(),commonNodes.begin(),commonNodes.end());
- }
- }
- }
- }
- }
-
template<int SPACEDIM>
void MEDCouplingPointSet::findNodeIdsNearPointAlg(std::vector<double>& bbox, const double *pos, int nbNodes, double eps,
std::vector<int>& c, std::vector<int>& cI) const
#include "MEDCouplingAutoRefCountObjectPtr.hxx"
#include <cmath>
+#include <sstream>
#include <iterator>
+#include <algorithm>
#include <functional>
using namespace ParaMEDMEM;
//
#include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingMemArray.txx"
#include "MEDCouplingFieldDouble.hxx"
#include "CellModel.hxx"
#include "VolSurfUser.txx"
bool areNodesMerged;
int newNbOfNodes;
int oldNbOfNodes=getNumberOfNodes();
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->buildPermArrayForMergeNode(oldNbOfNodes,prec,areNodesMerged,newNbOfNodes);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->buildPermArrayForMergeNode(prec,oldNbOfNodes,areNodesMerged,newNbOfNodes);
//mergeNodes
if(!areNodesMerged)
throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! ");
*/
DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
{
- DataArrayInt *ret=buildPermArrayForMergeNode(-1,precision,areNodesMerged,newNbOfNodes);
+ DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
if(areNodesMerged)
renumberNodes(ret->getConstPointer(),newNbOfNodes);
return ret;
*/
DataArrayInt *MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes)
{
- DataArrayInt *ret=buildPermArrayForMergeNode(-1,precision,areNodesMerged,newNbOfNodes);
+ DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
if(areNodesMerged)
renumberNodes2(ret->getConstPointer(),newNbOfNodes);
return ret;
setCoords(newCoords);
bool areNodesMerged;
int newNbOfNodes;
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=buildPermArrayForMergeNode(otherNbOfNodes,epsilon,areNodesMerged,newNbOfNodes);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=buildPermArrayForMergeNode(epsilon,otherNbOfNodes,areNodesMerged,newNbOfNodes);
if(!areNodesMerged)
{
setCoords(oldCoords);
#include "MEDCouplingMemArray.hxx"
#include <limits>
+#include <sstream>
using namespace ParaMEDMEM;
#include "MEDCouplingMemArray.hxx"
#include <cmath>
+#include <algorithm>
#include <functional>
using namespace ParaMEDMEM;
{
DataArrayInt *comm,*commI;
MEDCouplingUMesh *targetMesh=build3DTargetMesh_1();
- targetMesh->findCommonNodes(-1,1e-10,comm,commI);
+ targetMesh->findCommonNodes(1e-10,-1,comm,commI);
CPPUNIT_ASSERT_EQUAL(1,commI->getNumberOfTuples());
CPPUNIT_ASSERT_EQUAL(0,comm->getNumberOfTuples());
int newNbOfNodes;
//
targetMesh=build3DTargetMeshMergeNode_1();
CPPUNIT_ASSERT_EQUAL(31,targetMesh->getNumberOfNodes());
- targetMesh->findCommonNodes(-1,1e-10,comm,commI);
+ targetMesh->findCommonNodes(1e-10,-1,comm,commI);
CPPUNIT_ASSERT_EQUAL(3,commI->getNumberOfTuples());
CPPUNIT_ASSERT_EQUAL(6,comm->getNumberOfTuples());
const int commExpected[6]={1,27,28,29,23,30};
#include "MEDCouplingGaussLocalization.hxx"
#include <cmath>
+#include <algorithm>
#include <functional>
#include <iterator>
return res;
}
- PyObject *findCommonNodes(int limitNodeId, double prec) const throw(INTERP_KERNEL::Exception)
+ PyObject *findCommonNodes(double prec, int limitNodeId=-1) const throw(INTERP_KERNEL::Exception)
{
DataArrayInt *comm, *commIndex;
- self->findCommonNodes(limitNodeId,prec,comm,commIndex);
+ self->findCommonNodes(prec,limitNodeId,comm,commIndex);
PyObject *res = PyList_New(2);
PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
return self->keepSelectedComponents(tmp);
}
+ PyObject *findCommonTuples(double prec, int limitNodeId=-1) const throw(INTERP_KERNEL::Exception)
+ {
+ DataArrayInt *comm, *commIndex;
+ self->findCommonTuples(prec,limitNodeId,comm,commIndex);
+ PyObject *res = PyList_New(2);
+ PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+ PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+ return res;
+ }
+
void setSelectedComponents(const DataArrayDouble *a, PyObject *li) throw(INTERP_KERNEL::Exception)
{
std::vector<int> tmp;
def testFindCommonNodes(self):
targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1();
- comm,commI=targetMesh.findCommonNodes(-1,1e-10);
+ comm,commI=targetMesh.findCommonNodes(1e-10,-1);
self.assertEqual(1,commI.getNumberOfTuples());
self.assertEqual(0,comm.getNumberOfTuples());
o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI);
#
targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1();
self.assertEqual(31,targetMesh.getNumberOfNodes());
- comm,commI=targetMesh.findCommonNodes(-1,1e-10);
+ comm,commI=targetMesh.findCommonNodes(1e-10);# testing default parameter
self.assertEqual(3,commI.getNumberOfTuples());
self.assertEqual(6,comm.getNumberOfTuples());
commExpected=[1,27,28,29,23,30]