X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FINTERP_KERNEL%2FCellModel.cxx;h=acb6c0bfa4e37f8df8a9a81ade01f5badc1e6cfa;hb=714ec20d9675ab2c7d5530ae57656635def4e30f;hp=5a22ab1c409f83e1959165ea5d244775863a6f19;hpb=8763c12d01e33d6845dd53be65b001514d00bd42;p=tools%2Fmedcoupling.git diff --git a/src/INTERP_KERNEL/CellModel.cxx b/src/INTERP_KERNEL/CellModel.cxx index 5a22ab1c4..acb6c0bfa 100644 --- a/src/INTERP_KERNEL/CellModel.cxx +++ b/src/INTERP_KERNEL/CellModel.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D +// Copyright (C) 2007-2019 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 @@ -16,17 +16,21 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// Author : Anthony Geay (CEA/DEN) +// Author : Anthony Geay (EDF R&D) #include "CellModel.hxx" #include "InterpKernelException.hxx" +#include "DiameterCalculator.hxx" +#include "OrientationInverter.hxx" #include #include #include #include +unsigned char MEDCOUPLING2VTKTYPETRADUCER[INTERP_KERNEL::NORM_MAXTYPE+1]={1,3,21,5,9,7,22,34,23,28,35,MEDCOUPLING2VTKTYPETRADUCER_NONE,MEDCOUPLING2VTKTYPETRADUCER_NONE,MEDCOUPLING2VTKTYPETRADUCER_NONE,10,14,13,MEDCOUPLING2VTKTYPETRADUCER_NONE,12,MEDCOUPLING2VTKTYPETRADUCER_NONE,24,MEDCOUPLING2VTKTYPETRADUCER_NONE,16,27,MEDCOUPLING2VTKTYPETRADUCER_NONE,26,MEDCOUPLING2VTKTYPETRADUCER_NONE,29,32,MEDCOUPLING2VTKTYPETRADUCER_NONE,25,42,36,4}; + namespace INTERP_KERNEL { const char *CellModel::CELL_TYPES_REPR[]={"NORM_POINT1", "NORM_SEG2", "NORM_SEG3", "NORM_TRI3", "NORM_QUAD4",// 0->4 @@ -34,7 +38,7 @@ namespace INTERP_KERNEL "NORM_SEG4", "", "", "", "NORM_TETRA4",//10->14 "NORM_PYRA5", "NORM_PENTA6", "", "NORM_HEXA8", "",//15->19 "NORM_TETRA10", "", "NORM_HEXGP12", "NORM_PYRA13", "",//20->24 - "NORM_PENTA15", "", "NORM_HEXA27", "", "",//25->29 + "NORM_PENTA15", "", "NORM_HEXA27", "NORM_PENTA18", "",//25->29 "NORM_HEXA20", "NORM_POLYHED", "NORM_QPOLYG", "NORM_POLYL", "",//30->34 "", "", "", "", "",//35->39 "NORM_ERROR"}; @@ -98,6 +102,7 @@ namespace INTERP_KERNEL _map_of_unique_instance.insert(std::make_pair(NORM_HEXGP12,CellModel(NORM_HEXGP12))); _map_of_unique_instance.insert(std::make_pair(NORM_PYRA13,CellModel(NORM_PYRA13))); _map_of_unique_instance.insert(std::make_pair(NORM_PENTA15,CellModel(NORM_PENTA15))); + _map_of_unique_instance.insert(std::make_pair(NORM_PENTA18,CellModel(NORM_PENTA18))); _map_of_unique_instance.insert(std::make_pair(NORM_HEXA20,CellModel(NORM_HEXA20))); _map_of_unique_instance.insert(std::make_pair(NORM_HEXA27,CellModel(NORM_HEXA27))); _map_of_unique_instance.insert(std::make_pair(NORM_POLYGON,CellModel(NORM_POLYGON))); @@ -358,6 +363,26 @@ namespace INTERP_KERNEL _little_sons_con[8][0]=2; _little_sons_con[8][1]=5; _little_sons_con[8][2]=14; } break; + case NORM_PENTA18: + { + _nb_of_pts=18; _nb_of_sons=5; _dim=3; _linear_type=NORM_PENTA6; _is_simplex=false; + _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_QUAD9; _sons_type[3]=NORM_QUAD9; _sons_type[4]=NORM_QUAD9; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=6; _sons_con[0][4]=7; _sons_con[0][5]=8; _nb_of_sons_con[0]=6; + _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _sons_con[1][3]=11; _sons_con[1][4]=10; _sons_con[1][5]=9; _nb_of_sons_con[1]=6; + _sons_con[2][0]=0; _sons_con[2][1]=3; _sons_con[2][2]=4; _sons_con[2][3]=1; _sons_con[2][4]=12; _sons_con[2][5]=9; _sons_con[2][6]=13; _sons_con[2][7]=6; _sons_con[2][8]=15; _nb_of_sons_con[2]=9; + _sons_con[3][0]=1; _sons_con[3][1]=4; _sons_con[3][2]=5; _sons_con[3][3]=2; _sons_con[3][4]=13; _sons_con[3][5]=10; _sons_con[3][6]=14; _sons_con[3][7]=7; _sons_con[3][8]=16; _nb_of_sons_con[3]=9; + _sons_con[4][0]=2; _sons_con[4][1]=4; _sons_con[4][2]=5; _sons_con[4][3]=0; _sons_con[4][4]=14; _sons_con[4][5]=11; _sons_con[4][6]=12; _sons_con[4][7]=8; _sons_con[4][8]=17; _nb_of_sons_con[4]=9; _quadratic=true; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=6; _nb_of_little_sons=9; + _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=7; + _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; _little_sons_con[2][2]=8; + _little_sons_con[3][0]=3; _little_sons_con[3][1]=4; _little_sons_con[3][2]=9; + _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; _little_sons_con[4][2]=10; + _little_sons_con[5][0]=5; _little_sons_con[5][1]=3; _little_sons_con[5][2]=11; + _little_sons_con[6][0]=0; _little_sons_con[6][1]=3; _little_sons_con[6][2]=12; + _little_sons_con[7][0]=1; _little_sons_con[7][1]=4; _little_sons_con[7][2]=13; + _little_sons_con[8][0]=2; _little_sons_con[8][1]=5; _little_sons_con[8][2]=14; + } + break; case NORM_HEXA20: { _nb_of_pts=20; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _is_simplex=false; @@ -426,29 +451,51 @@ namespace INTERP_KERNEL /*! * Equivalent to getNumberOfSons except that this method deals with dynamic type. */ - unsigned CellModel::getNumberOfSons2(const int *conn, int lgth) const + unsigned CellModel::getNumberOfSons2(const mcIdType *conn, mcIdType lgth) const { if(!isDynamic()) return getNumberOfSons(); if(_dim==2) { if(_type==NORM_POLYGON) - return lgth; + return FromIdType(lgth); else - return lgth/2; + return FromIdType(lgth/2); } else if(_dim==1) - return lgth;//NORM_POLYL + return FromIdType(lgth);//NORM_POLYL else - return std::count(conn,conn+lgth,-1)+1; + return (unsigned)std::count(conn,conn+lgth,-1)+1; } - unsigned CellModel::getNumberOfEdgesIn3D(const int *conn, int lgth) const + unsigned CellModel::getNumberOfEdgesIn3D(const mcIdType *conn, mcIdType lgth) const { if(!isDynamic()) return _nb_of_little_sons; else//polyhedron - return (lgth-std::count(conn,conn+lgth,-1))/2; + return FromIdType(lgth-ToIdType(std::count(conn,conn+lgth,-1)/2)); + } + + /*! + * \sa fillMicroEdgeNodalConnectivity + */ + unsigned CellModel::getNumberOfMicroEdges() const + { + unsigned mul(isQuadratic()?2:1); + if(!isDynamic()) + { + switch(getDimension()) + { + case 2: + return mul*getNumberOfSons(); + case 3: + return mul*_nb_of_little_sons; + default: + throw INTERP_KERNEL::Exception("CellModel::getNumberOfMacroEdges : only 2D and 3D cells support this !"); + } + } + else + throw INTERP_KERNEL::Exception("CellModel::getNumberOfMacroEdges : not supported by dynamic type !"); } NormalizedCellType CellModel::getCorrespondingPolyType() const @@ -504,7 +551,7 @@ namespace INTERP_KERNEL /*! * \b WARNING this method do not manage correctly types that return true at the call of isDynamic. Use fillSonCellNodalConnectivity2 instead. */ - unsigned CellModel::fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const + unsigned CellModel::fillSonCellNodalConnectivity(int sonId, const mcIdType *nodalConn, mcIdType *sonNodalConn) const { unsigned nbOfTurnLoop=_nb_of_sons_con[sonId]; const unsigned *sonConn=_sons_con[sonId]; @@ -513,7 +560,7 @@ namespace INTERP_KERNEL return nbOfTurnLoop; } - unsigned CellModel::fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const + unsigned CellModel::fillSonCellNodalConnectivity2(int sonId, const mcIdType *nodalConn, mcIdType lgth, mcIdType *sonNodalConn, NormalizedCellType& typeOfSon) const { typeOfSon=getSonType2(sonId); if(!isDynamic()) @@ -528,7 +575,7 @@ namespace INTERP_KERNEL sonNodalConn[1]=nodalConn[(sonId+1)%lgth]; return 2; } - else + else // NORM_QPOLYG { sonNodalConn[0]=nodalConn[sonId]; sonNodalConn[1]=nodalConn[(sonId+1)%(lgth/2)]; @@ -538,15 +585,15 @@ namespace INTERP_KERNEL } else if(_dim==3) {//polyedron - const int *where=nodalConn; + const mcIdType *where=nodalConn; for(int i=0;iHEXA27 */ - unsigned CellModel::fillSonCellNodalConnectivity4(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const + unsigned CellModel::fillSonCellNodalConnectivity4(int sonId, const mcIdType *nodalConn, mcIdType lgth, mcIdType *sonNodalConn, NormalizedCellType& typeOfSon) const { if(_type==NORM_HEXA8) { @@ -567,7 +614,7 @@ namespace INTERP_KERNEL return fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); } - unsigned CellModel::fillSonEdgesNodalConnectivity3D(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const + unsigned CellModel::fillSonEdgesNodalConnectivity3D(int sonId, const mcIdType *nodalConn, mcIdType lgth, mcIdType *sonNodalConn, NormalizedCellType& typeOfSon) const { if(!isDynamic()) { @@ -591,13 +638,103 @@ namespace INTERP_KERNEL throw INTERP_KERNEL::Exception("CellModel::fillSonEdgesNodalConnectivity3D : not implemented yet for NORM_POLYHED !"); } + /*! + * \sa getNumberOfMicroEdges + */ + unsigned CellModel::fillMicroEdgeNodalConnectivity(int sonId, const mcIdType *nodalConn, mcIdType *sonNodalConn, NormalizedCellType& typeOfSon) const + { + if(isQuadratic()) + { + int edgeId(sonId/2),subEdgeId(sonId%2); + typeOfSon=NORM_SEG2; + const unsigned *sonConn(0); + switch(getDimension()) + { + case 2: + { + sonConn=_sons_con[edgeId]; + break; + } + case 3: + { + sonConn=_little_sons_con[edgeId]; + break; + } + default: + throw INTERP_KERNEL::Exception("CellModel::fillMicroEdgeNodalConnectivity : only 2D and 3D cells support this !"); + } + const unsigned tmp[3]={sonConn[0],sonConn[2],sonConn[1]}; + sonNodalConn[0]=nodalConn[tmp[subEdgeId]]; + sonNodalConn[1]=nodalConn[tmp[subEdgeId+1]]; + return 2; + } + else + { + switch(getDimension()) + { + case 2: + return fillSonCellNodalConnectivity2(sonId,nodalConn,0,sonNodalConn,typeOfSon); + case 3: + return fillSonEdgesNodalConnectivity3D(sonId,nodalConn,0,sonNodalConn,typeOfSon); + default: + throw INTERP_KERNEL::Exception("CellModel::fillMicroEdgeNodalConnectivity : only 2D and 3D cells support this #2 !"); + } + } + } + + void CellModel::changeOrientationOf2D(mcIdType *nodalConn, unsigned int sz) const + { + if(sz<1) + return ; + if(!isQuadratic()) + { + std::vector tmp(sz-1); + std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin()); + std::copy(tmp.begin(),tmp.end(),nodalConn+1); + } + else + { + unsigned int sz2(sz/2); + std::vector tmp0(sz2-1),tmp1(sz2); + std::copy(nodalConn+1,nodalConn+sz2,tmp0.rbegin()); + std::copy(nodalConn+sz2,nodalConn+sz,tmp1.rbegin()); + std::copy(tmp0.begin(),tmp0.end(),nodalConn+1); + std::copy(tmp1.begin(),tmp1.end(),nodalConn+sz2); + } + } + + void CellModel::changeOrientationOf1D(mcIdType *nodalConn, unsigned int sz) const + { + if(!isDynamic()) + { + if(sz==2 || sz==3) + { + std::swap(nodalConn[0],nodalConn[1]); + return ; + } + else if(sz==4) + { + std::swap(nodalConn[0],nodalConn[1]); + std::swap(nodalConn[2],nodalConn[3]); + } + else + throw Exception("CellModel::changeOrientationOf1D : unrecognized 1D cell type !"); + } + else + { + std::vector tmp(sz-1); + std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin()); + std::copy(tmp.begin(),tmp.end(),nodalConn+1); + } + } + //================================================================================ /*! * \brief Return number of nodes in sonId-th son of a Dynamic() cell */ //================================================================================ - unsigned CellModel::getNumberOfNodesConstituentTheSon2(unsigned sonId, const int *nodalConn, int lgth) const + unsigned CellModel::getNumberOfNodesConstituentTheSon2(unsigned sonId, const mcIdType *nodalConn, mcIdType lgth) const { if(!isDynamic()) return getNumberOfNodesConstituentTheSon(sonId); @@ -611,14 +748,14 @@ namespace INTERP_KERNEL } else if(_dim==3) {//polyedron - const int *where=nodalConn; + const mcIdType *where=nodalConn; for(unsigned int i=0;i tmp(2*lgth); - std::vector::iterator it=std::copy(conn1,conn1+lgth,tmp.begin()); + std::vector tmp(2*lgth); + std::vector::iterator it=std::copy(conn1,conn1+lgth,tmp.begin()); std::copy(conn1,conn1+lgth,it); it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth); if(it==tmp.begin()) return true; if(it!=tmp.end()) return _dim!=1; - std::vector::reverse_iterator it2=std::search(tmp.rbegin(),tmp.rend(),conn2,conn2+lgth); + std::vector::reverse_iterator it2=std::search(tmp.rbegin(),tmp.rend(),conn2,conn2+lgth); if(it2!=tmp.rend()) return false; throw INTERP_KERNEL::Exception("CellModel::getOrientationStatus : Request of orientation status of non equal connectively cells !"); @@ -653,11 +790,11 @@ namespace INTERP_KERNEL { if(_dim!=1) { - std::vector tmp(lgth); - std::vector::iterator it=std::copy(conn1,conn1+lgth/2,tmp.begin()); + std::vector tmp(lgth); + std::vector::iterator it=std::copy(conn1,conn1+lgth/2,tmp.begin()); std::copy(conn1,conn1+lgth/2,it); it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth/2); - int d=std::distance(tmp.begin(),it); + std::size_t d=std::distance(tmp.begin(),it); if(it==tmp.end()) return false; it=std::copy(conn1+lgth/2,conn1+lgth,tmp.begin()); @@ -665,17 +802,17 @@ namespace INTERP_KERNEL it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth); if(it==tmp.end()) return false; - int d2=std::distance(tmp.begin(),it); + std::size_t d2=std::distance(tmp.begin(),it); return d==d2; } else { - int p=(lgth+1)/2; - std::vector tmp(2*p); - std::vector::iterator it=std::copy(conn1,conn1+p,tmp.begin()); + mcIdType p=(lgth+1)/2; + std::vector tmp(2*p); + std::vector::iterator it=std::copy(conn1,conn1+p,tmp.begin()); std::copy(conn1,conn1+p,it); it=std::search(tmp.begin(),tmp.end(),conn2,conn2+p); - int d=std::distance(tmp.begin(),it); + std::size_t d=std::distance(tmp.begin(),it); if(it==tmp.end()) return false; tmp.resize(2*p-2); @@ -684,10 +821,199 @@ namespace INTERP_KERNEL it=std::search(tmp.begin(),tmp.end(),conn2+p,conn2+lgth); if(it==tmp.end()) return false; - int d2=std::distance(tmp.begin(),it); + std::size_t d2=std::distance(tmp.begin(),it); return d==d2; } } } + + DiameterCalculator *CellModel::buildInstanceOfDiameterCalulator(int spaceDim) const + { + switch(_type) + { + case NORM_TRI3: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorTRI3S2; + case 3: + return new DiameterCalulatorTRI3S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI3 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_QUAD4: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorQUAD4S2; + case 3: + return new DiameterCalulatorQUAD4S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD4 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_TRI6: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorTRI6S2; + case 3: + return new DiameterCalulatorTRI6S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI6 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_TRI7: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorTRI7S2; + case 3: + return new DiameterCalulatorTRI7S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI7 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_QUAD8: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorQUAD8S2; + case 3: + return new DiameterCalulatorQUAD8S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD8 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_QUAD9: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorQUAD9S2; + case 3: + return new DiameterCalulatorQUAD9S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD9 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_TETRA4: + { + if(spaceDim==3) + return new DiameterCalulatorTETRA4; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA4 space dimension 3 expected !"); + } + case NORM_TETRA10: + { + if(spaceDim==3) + return new DiameterCalulatorTETRA10; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA10 space dimension 3 expected !"); + } + case NORM_HEXA8: + { + if(spaceDim==3) + return new DiameterCalulatorHEXA8; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA8 space dimension 3 expected !"); + } + case NORM_HEXA20: + { + if(spaceDim==3) + return new DiameterCalulatorHEXA20; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA20 space dimension 3 expected !"); + } + case NORM_HEXA27: + { + if(spaceDim==3) + return new DiameterCalulatorHEXA27; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA27 space dimension 3 expected !"); + } + case NORM_PENTA6: + { + if(spaceDim==3) + return new DiameterCalulatorPENTA6; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA6 space dimension 3 expected !"); + } + case NORM_PENTA15: + { + if(spaceDim==3) + return new DiameterCalulatorPENTA15; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA15 space dimension 3 expected !"); + } + case NORM_PYRA5: + { + if(spaceDim==3) + return new DiameterCalulatorPYRA5; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA5 space dimension 3 expected !"); + } + case NORM_PYRA13: + { + if(spaceDim==3) + return new DiameterCalulatorPYRA13; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA13 space dimension 3 expected !"); + } + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : implemented only for TRI3, QUAD4, TETRA4, HEXA8, PENTA6, PYRA5 !"); + } + } + OrientationInverter *CellModel::buildOrientationInverter() const + { + switch(_type) + { + case NORM_SEG2: + return new OrientationInverterSEG2; + case NORM_SEG3: + return new OrientationInverterSEG3; + case NORM_TRI3: + case NORM_QUAD4: + return new OrientationInverter2DLinear(getNumberOfNodes()); + case NORM_TRI6: + case NORM_QUAD8: + return new OrientationInverter2DQuadratic(getNumberOfNodes()); + case NORM_POLYGON: + return new OrientationInverterPolygon; + case NORM_QPOLYG: + return new OrientationInverterQPolygon; + case NORM_TETRA4: + return new OrientationInverterTetra4; + case NORM_PYRA5: + return new OrientationInverterPyra5; + case NORM_TETRA10: + return new OrientationInverterTetra10; + case NORM_PYRA13: + return new OrientationInverterPyra13; + case NORM_PENTA6: + case NORM_HEXA8: + return new OrientationInverter3DExtrusionLinear(getNumberOfNodes()); + case NORM_PENTA15: + case NORM_HEXA20: + return new OrientationInverter3DExtrusionQuadratic(getNumberOfNodes()); + default: + { + std::ostringstream oss; oss << "CellModel::buildOrientationInverter : not managed geometric type " << getRepr() << " yet !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + } + } }