1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
31 #include "MEDMEM_Support.hxx"
32 #include "MEDMEM_DriversDef.hxx"
33 #include "MEDMEM_Mesh.hxx"
36 using namespace MED_EN;
37 using namespace MEDMEM;
39 #define MED_NBR_GEOMETRIE_MAILLE 15
42 \defgroup SUPPORT_general General information
44 \defgroup SUPPORT_creation Creation methods
45 The creation of a support requires a number of information
46 which is supplied to the MedMem library with the following methods.
47 When the support is defined on all elements, the creation method is
48 very simple, for the element list is implicitly defined.
50 \defgroup SUPPORT_query Query methods
52 \defgroup SUPPORT_constructors Constructors
54 \defgroup SUPPORT_advanced Advanced methods
60 /* This class is a generic class for family and group */
65 //--------------------------------------------------------------------------
66 SUPPORT::SUPPORT(): _name(""), _description("None"), _mesh((MESH*)NULL),
67 _entity(MED_CELL), _numberOfGeometricType(0),
69 _totalNumberOfElements(0),
70 _number((MEDSKYLINEARRAY*)NULL)
71 //--------------------------------------------------------------------------
73 MESSAGE_MED("SUPPORT::SUPPORT()");
77 \addtogroup SUPPORT_constructors
82 Constructor of a support lying on mesh \a Mesh. By default,
83 the support lies on all elements of type \a Entity.
84 Partial support can be described using \a setpartial method.
86 \param Mesh Pointer to the mesh on which the support lies
87 \param Name Support name (should not exceed MED_TAILLE_NOM as defined in Med - i.e. 32 characters)
88 \param Entity Entity type of the support (MED_CELL,MED_FACE,MED_EDGE, MED_NODE)
90 //--------------------------------------------------------------------------
91 SUPPORT::SUPPORT(MESH* Mesh, string Name/*=""*/, MED_EN::medEntityMesh Entity/*=MED_CELL*/):
92 _name(Name), _description("None"), _mesh(Mesh), _entity(Entity),
93 _numberOfGeometricType(0), _isOnAllElts(true),
94 _totalNumberOfElements(0), _number((MEDSKYLINEARRAY*)NULL)
95 //--------------------------------------------------------------------------
97 MESSAGE_MED("SUPPORT::SUPPORT(MESH*Mesh,string Name,medEntityMesh Entity)");
104 //--------------------------------------------------------------------------
105 SUPPORT::SUPPORT(const SUPPORT & m)
106 //--------------------------------------------------------------------------
108 const char* LOC = "SUPPORT::SUPPORT(SUPPORT & m) : ";
112 _description = m._description ;
113 _mesh = m._mesh ; // on recopie uniquement l'adresse
115 _numberOfGeometricType = m._numberOfGeometricType;
117 if (m._geometricType)
118 _geometricType.set(_numberOfGeometricType,m._geometricType);
120 _isOnAllElts = m._isOnAllElts;
122 if (m._numberOfElements)
123 _numberOfElements.set(_numberOfGeometricType,m._numberOfElements);
125 _totalNumberOfElements = m._totalNumberOfElements;
127 if (m._isOnAllElts == false && m._number ) // m may be not filled SUPPORTClient
128 _number = new MEDSKYLINEARRAY(* m._number);
130 _number = (MEDSKYLINEARRAY *) NULL;
132 _profilNames=m._profilNames;
141 Affectation operator. operator = perform et deep copy except for attribute _mesh
144 //--------------------------------------------------------------------------
145 SUPPORT & SUPPORT::operator=(const SUPPORT & m)
146 //--------------------------------------------------------------------------
148 const char* LOC = "SUPPORT::operator=(const SUPPORT & m) : ";
151 if ( this == &m ) return *this;
154 _description = m._description;
155 _mesh = m._mesh ; // on recopie uniquement l'adresse
157 _numberOfGeometricType = m._numberOfGeometricType;
158 if (m._geometricType)
159 _geometricType.set(_numberOfGeometricType,m._geometricType);
160 _isOnAllElts = m._isOnAllElts;
161 if (m._numberOfElements)
162 _numberOfElements.set(_numberOfGeometricType,m._numberOfElements);
163 _totalNumberOfElements = m._totalNumberOfElements;
165 if (m._isOnAllElts == false) {
166 if (_number) delete _number;
167 if ( m._number ) // m may be not filled SUPPORTClient
168 _number = new MEDSKYLINEARRAY(* m._number);
170 _number = (MEDSKYLINEARRAY *) NULL;
173 _number = (MEDSKYLINEARRAY *) NULL;
175 _profilNames=m._profilNames;
188 MESSAGE_MED("Destructeur ~SUPPORT()");
189 clearDataOnNumbers();
195 //--------------------------------------------------
196 ostream & MEDMEM::operator<<(ostream &os, const SUPPORT &my)
197 //--------------------------------------------------
199 os << "Name : "<< my.getName() << endl ;
200 os << "Description : "<< my.getDescription() << endl ;
202 if (my.getMesh() == NULL)
203 os << " Mesh not defined." << endl ;
205 os << " Mesh defined." << endl;
207 os << my.getMeshName() << endl ;
208 os << "Entity : "<<MED_EN::entNames[my._entity] << endl;
209 os << "Entity list : "<< endl;
210 if ( my._isOnAllElts )
211 os << "Is on all entities."<< endl;
213 os << "Is not on all entities. "<< endl;
214 if ( my._number ) // m may be not filled SUPPORTClient
215 os << *my.getNumber(MED_ALL_ELEMENTS);
217 int numberoftypes = my._numberOfGeometricType ;
218 os << "NumberOfTypes : "<<numberoftypes<<endl;
219 PointerOf<medGeometryElement> types = my._geometricType;
220 for (int j=0;j<numberoftypes;j++) {
221 int numberOfElements = my._numberOfElements[j];
222 os << " On Type "<<MED_EN::geoNames[types[j]]
223 <<" : there is(are) "<<numberOfElements<<" element(s) and " <<endl;
225 int nbProfilNames = my._profilNames.size();
226 os<<"Number of profil names = "<<nbProfilNames<<endl;
227 for(int j=0; j<nbProfilNames; j++) {
228 os<<" Profil Name N"<<j+1<<" = "<<my._profilNames[j]<<endl;
234 Updade the SUPPORT attributs with right MESH information.
236 It has an effect only if SUPPORT is on all elements.
238 No more need in future release.
240 //-------------------
241 void SUPPORT::update()
242 //-------------------
244 const char* LOC = "SUPPORT::update() : ";
249 if (_entity == MED_NODE)
251 _numberOfGeometricType=1 ;
252 _geometricType.set(1);
253 _geometricType[0]=MED_POINT1;
254 _numberOfElements.set(1);
255 _numberOfElements[0]=_mesh->getNumberOfNodes(); // Vérifier le pointeur !
256 _totalNumberOfElements=_numberOfElements[0];
259 { // we duplicate information from _mesh
\ 1
260 _numberOfGeometricType=_mesh->getNumberOfTypesWithPoly(_entity);
261 SCRUTE_MED(_numberOfGeometricType);
262 medGeometryElement * allType = _mesh->getTypesWithPoly(_entity);
263 _geometricType.set(_numberOfGeometricType,allType );
264 _numberOfElements.set(_numberOfGeometricType);
265 _totalNumberOfElements=0;
266 for (int i=0;i<_numberOfGeometricType;i++)
268 _numberOfElements[i]=_mesh->getNumberOfElementsWithPoly(_entity,_geometricType[i]) ;
269 _totalNumberOfElements+=_numberOfElements[i];
275 SCRUTE_MED(_numberOfGeometricType);
280 Get the field value index (in fortran mode) from the support global number.
281 Becareful, it doesn't take care of the field number of components
283 //-------------------
284 int SUPPORT::getValIndFromGlobalNumber(const int number) const throw (MEDEXCEPTION)
285 //-------------------
287 const char * LOC="getValIndFromGlobalNumber(const int number) : ";
290 if (_isOnAllElts) return number;
292 int nbOfEltsThis = getNumberOfElements(MED_ALL_ELEMENTS);
294 const int *eltsThis = _number->getValue();
299 for(iThis=0;iThis<nbOfEltsThis && !found;)
300 if(eltsThis[iThis]==number)
303 int valInd = iThis+1;
310 cout << "----Contenu du skyline : ---------------------" << *_number << endl;
313 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't find the global number |"
314 << number << "| in Support |"
315 << getName() << "|" ));
317 // It should never arrive here !!
324 \addtogroup SUPPORT_advanced
330 Blends the given SUPPORT mySupport into the calling object SUPPORT.
334 SUPPORT myOtherSupport ;
336 mySupport.blending(myOtherSupport) ;
338 Support \a mySupport now contains a union of the elements originally
339 contained in \a mySupport and \a myOtherSupport.
341 //-------------------
342 void SUPPORT::blending(SUPPORT * mySupport) throw (MEDEXCEPTION)
343 //-------------------
345 const char * LOC="SUPPORT::blending(SUPPORT *) : ";
347 if (_entity!=mySupport->getEntity())
348 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Entities are different !"));
349 if(!(*_mesh == *mySupport->getMesh()))
350 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Mesh are different !"));
353 if(mySupport->isOnAllElements())
358 if(mySupport->_totalNumberOfElements==0)
360 const int *ids=getNumber(MED_ALL_ELEMENTS);
361 set<int> idsSet(ids,ids+getNumberOfElements(MED_ALL_ELEMENTS));
362 const int *idsMySupport=mySupport->getNumber(MED_ALL_ELEMENTS);
363 int mySupportSize=mySupport->getNumberOfElements(MED_ALL_ELEMENTS);
364 set<int>::iterator iter;
365 for(int i=0;i<mySupportSize;i++)
366 idsSet.insert(idsMySupport[i]);
367 int size=idsSet.size();
372 for(iter=idsSet.begin();iter!=idsSet.end();iter++)
373 idsList.push_back(*iter);
375 MESSAGE_MED(LOC << " size Set " << idsSet.size() << " size List " << idsList.size());
377 if(_entity==MED_NODE)
378 fillFromNodeList(idsList);
380 fillFromElementList(idsList);
383 clearDataOnNumbers();
389 \addtogroup SUPPORT_creation
394 This function allows the user to set a support not on all entities Entity,
395 it should be used after an initialisation with the constructor
396 SUPPORT(MESH* Mesh, string Name="", medEntityMesh Entity=MED_CELL).
397 It allocates and initialises all the attributs of the class SUPPORT.
399 \param Description string describing the support for information purposes (should not exceed MED_TAILLE_DESC length - i.e. 200 characters)
400 \param NumberOfGeometricType number of geometric types contained in the support
401 \param TotalNumberOfElements number of elements in the support
402 \param GeometricType array describing the geometric types (must be consistent with the entity that was passed as an argument to the support constructor)
403 \param NumberOfElements array describing the number of elements for each type
404 \param NumberValue array of IDs of the elements that constitute the group.
406 The following example refers to the mesh given in the mesh connectivity example.
407 It creates a group containing the two cells on the right (the quadratic triangle and the quadrangle on the right).
410 // creating SUPPORT on cells with one value per cell
411 SUPPORT right_group(mesh, MED_CELL, 1);
413 string description = "right group";
414 int number_of_types=2;
415 int number_of_elements=2;
416 medGeometryElement geom_types[2]={MED_QUAD4, MED_TRIA6};
417 int number_of_elem_per_type[2]={1,1};
418 int number_value[2]={3,4};
420 //defining the region of the support
421 right_group.setpartial(description, number_of_types,
422 number_of_elements, geom_types,
423 number_of_elem_per_type, number_value);
426 When MED_POLYGON or MED_POLYHEDRON elements are included in the support,
427 their global number should be given. For instance, on a mesh having ten MED_TRIA3
428 and five MED_POLYGON, the number of the first polygonal element is 11.
431 //-------------------
432 void SUPPORT::setpartial(string Description, int NumberOfGeometricType,
433 int TotalNumberOfElements,
434 MED_EN::medGeometryElement *GeometricType,
435 int *NumberOfElements, int *NumberValue)
436 //-------------------
438 const char * LOC = "SUPPORT::setpartial(string , int , int , medGeometryElement * , int * , int *) : " ;
441 _isOnAllElts = false ;
443 _description=Description;
445 _numberOfGeometricType=NumberOfGeometricType;
446 _geometricType.set(NumberOfGeometricType);
447 _numberOfElements.set(NumberOfGeometricType);
448 _totalNumberOfElements = TotalNumberOfElements;
450 int * index = new int[_numberOfGeometricType+1];
453 for (int i=0;i<_numberOfGeometricType;i++) {
454 if(GeometricType[i]/100 != elemDim)
456 elemDim=GeometricType[i]/100;
458 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"unhomogeneous geometric types (dimension) !"));
459 _geometricType[i] = GeometricType[i] ;
460 _numberOfElements[i] = NumberOfElements[i] ;
461 index[i+1] = index[i]+NumberOfElements[i] ;
464 if (_number!=NULL) delete _number ;
465 _number = new MEDSKYLINEARRAY(_numberOfGeometricType,_totalNumberOfElements,index,NumberValue);
469 // PAL16854(Partial support on nodes):
470 // giving a default value to profile names
471 vector<string> prof_names( NumberOfGeometricType);
472 for (int itype=0; itype < NumberOfGeometricType; itype++)
474 ostringstream typestr;
475 typestr<<_name<<"_type"<<_geometricType[itype];
476 prof_names[itype]=typestr.str();
478 setProfilNames(prof_names);
487 This function allows the user to set a support not on all entities Entity,
488 it should be used after an initialisation of :
489 SUPPORT(MESH* Mesh, string Name="", medEntityMesh Entity=MED_CELL) and
490 after calling at least setGeometricType and perharps setEntity.
491 It allocates and initialises all the attributs of the class SUPPORT but
492 doesn't set a description, a SUPPORT name, a meshName and an associated MESH.
496 //-------------------
497 void SUPPORT::setpartial(MEDSKYLINEARRAY * number, bool shallowCopy) throw (MEDEXCEPTION)
498 //-------------------
500 const char * LOC = "SUPPORT::setpartial(MEDSKYLINEARRAY * number) : " ;
503 if ( ! _geometricType )
504 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"SUPPORT must contains"
505 << " a geometric type list" )) ;
507 _numberOfGeometricType = number->getNumberOf();
509 _numberOfElements.set(_numberOfGeometricType);
511 for (int i=0; i< _numberOfGeometricType; i++)
512 _numberOfElements[i] = number->getNumberOfI(i+1);
514 _totalNumberOfElements = number->getLength();
516 _isOnAllElts = false ;
518 if (_number!=NULL) delete _number ;
523 _number = new MEDSKYLINEARRAY(*number);
525 // cout << *_number << endl;
530 void SUPPORT::setpartial_fromfile(MEDSKYLINEARRAY * number, bool shallowCopy) throw (MEDEXCEPTION)
531 //-------------------
533 const char* LOC = "SUPPORT::setpartial_fromfile(MEDSKYLINEARRAY * number) : ";
537 _number_fromfile = number;
539 _number_fromfile = new MEDSKYLINEARRAY(*number);
544 void SUPPORT::setProfilNames(vector<string> profilNames) throw (MEDEXCEPTION){
546 const char * LOC = "SUPPORT::setProfilNames(vector<string> profilNames) : " ;
550 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"SUPPORT shouldn't be on all elements"
551 << " while setting profil name list" )) ;
553 if ( ! _geometricType || _numberOfGeometricType==0 )
554 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"SUPPORT must contains"
555 << " a least one geometric type" )) ;
558 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"SUPPORT must contains"
559 << " a profil number list before setting"
560 << " the associated profil name list" )) ;
562 if ( ( profilNames.size() != _number->getNumberOf() ) &&
563 ( profilNames.size() !=_numberOfGeometricType ) ) {
564 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The profil name list size : "<< profilNames.size()
565 << " must be equal to the number of geometric type : "
566 << _numberOfGeometricType << " (_number->getNumberOf() : "
567 << _number->getNumberOf() << " )"
572 _profilNames = profilNames;
578 vector<string> SUPPORT::getProfilNames() const throw (MEDEXCEPTION)
584 \addtogroup SUPPORT_advanced
589 This method gets the boundary elements of the mesh. The support has to be
590 build using the constructor SUPPORT(MESH *,string, medEntityMesh) or
591 SUPPORT() followed by setMesh(MESH*) setName(string) and
592 setEntity(medEntityMesh) before using this method.
594 //-------------------
595 void SUPPORT::getBoundaryElements() throw (MEDEXCEPTION)
596 //-------------------
598 const char * LOC = "SUPPORT::getBoundaryElements() : " ;
601 if (_mesh == (MESH*)NULL) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"You shlould use the appropriate SUPPORT Constructor before calling this method"));
603 int spaceDimension = _mesh->getSpaceDimension();
605 if (spaceDimension == 3)
606 if (_entity != MED_FACE)
607 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined in 3D mesh for entity "<<_entity<<" !"));
608 if (spaceDimension == 2)
609 if (_entity != MED_EDGE)
610 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined in 2D mesh for entity "<<_entity<<" !"));
614 const int * myConnectivityValue = _mesh->getReverseConnectivity(MED_DESCENDING) ;
615 const int * myConnectivityIndex = _mesh->getReverseConnectivityIndex(MED_DESCENDING) ;
616 int numberOf = _mesh->getNumberOfElements(_entity,MED_ALL_ELEMENTS) ;
617 list<int> myElementsList ;
619 SCRUTE_MED(numberOf) ;
620 for (int i=0 ; i<numberOf; i++)
621 if (myConnectivityValue[myConnectivityIndex[i]] == 0) {
623 myElementsList.push_back(i+1) ;
627 // Well, we must know how many geometric type we have found
628 int * myListArray = new int[size] ;
630 list<int>::iterator myElementsListIt ;
631 for (myElementsListIt=myElementsList.begin();myElementsListIt!=myElementsList.end();myElementsListIt++) {
632 myListArray[id]=(*myElementsListIt) ;
634 SCRUTE_MED(myListArray[id]);
638 int numberOfGeometricType ;
639 medGeometryElement* geometricType ;
640 int * geometricTypeNumber ;
641 int * numberOfElements ;
642 //MEDSKYLINEARRAY * mySkyLineArray = new MEDSKYLINEARRAY() ;
643 int * mySkyLineArrayIndex ;
645 int numberOfType = _mesh->getNumberOfTypes(_entity) ;
646 if (numberOfType == 1) { // wonderfull : it's easy !
647 numberOfGeometricType = 1 ;
648 geometricType = new medGeometryElement[1] ;
649 const medGeometryElement * allType = _mesh->getTypes(_entity);
650 geometricType[0] = allType[0] ;
651 geometricTypeNumber = new int[1] ; // not use, but initialized to nothing
652 geometricTypeNumber[0] = 0 ;
653 numberOfElements = new int[1] ;
654 numberOfElements[0] = size ;
655 mySkyLineArrayIndex = new int[2] ;
656 mySkyLineArrayIndex[0]=1 ;
657 mySkyLineArrayIndex[1]=1+size ;
660 map<medGeometryElement,int> theType ;
661 for (myElementsListIt=myElementsList.begin();myElementsListIt!=myElementsList.end();myElementsListIt++) {
662 medGeometryElement myType = _mesh->getElementType(_entity,*myElementsListIt) ;
663 if (theType.find(myType) != theType.end() )
668 numberOfGeometricType = theType.size() ;
669 geometricType = new medGeometryElement[numberOfGeometricType] ;
670 //const medGeometryElement * allType = _mesh->getTypes(_entity); !! UNUSED VARIABLE !!
671 geometricTypeNumber = new int[numberOfGeometricType] ; // not use, but initialized to nothing
672 numberOfElements = new int[numberOfGeometricType] ;
673 mySkyLineArrayIndex = new int[numberOfGeometricType+1] ;
675 mySkyLineArrayIndex[0]=1 ;
676 map<medGeometryElement,int>::iterator theTypeIt ;
677 for (theTypeIt=theType.begin();theTypeIt!=theType.end();theTypeIt++) {
678 geometricType[index] = (*theTypeIt).first ;
679 geometricTypeNumber[index] = 0 ;
680 numberOfElements[index] = (*theTypeIt).second ;
681 mySkyLineArrayIndex[index+1]=mySkyLineArrayIndex[index]+numberOfElements[index] ;
685 //mySkyLineArray->setMEDSKYLINEARRAY(numberOfGeometricType,size,mySkyLineArrayIndex,myListArray) ;
686 MEDSKYLINEARRAY * mySkyLineArray = new MEDSKYLINEARRAY(numberOfGeometricType,size,mySkyLineArrayIndex,myListArray) ;
688 setNumberOfGeometricType(numberOfGeometricType) ;
689 setGeometricType(geometricType) ;
690 //for (int i=0;i<numberOfGeometricType;i++)
692 // _geometricType[i] = geometricType[i];
695 setNumberOfElements(numberOfElements) ;
696 //setTotalNumberOfElements(size) ;
697 // setNumber(mySkyLineArray) ;
699 _number = new MEDSKYLINEARRAY(numberOfGeometricType,size);
701 _number->setIndex(mySkyLineArrayIndex);
703 for (int i=0;i<size;i++)
705 _number->setIndexValue(i+1,myListArray[i]);
708 delete[] numberOfElements;
709 delete[] geometricTypeNumber;
710 delete[] geometricType;
711 delete[] mySkyLineArrayIndex;
712 delete[] myListArray;
713 delete mySkyLineArray;
719 Intersects \a mySupport into the calling SUPPORT object.
720 If A.intersecting(B) is called, on output, \f$ A \f$ contains \f$A \cap B\f$.
722 //-------------------
723 void SUPPORT::intersecting(SUPPORT * mySupport) throw (MEDEXCEPTION)
725 const char * LOC="SUPPORT::intersecting(SUPPORT *) : ";
727 if (_entity!=mySupport->getEntity())
728 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Entities are different !"));
729 if(!(*_mesh == *mySupport->getMesh()))
730 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Mesh are different !"));
731 if(mySupport->isOnAllElements())
738 if(_totalNumberOfElements==0)
740 const int *ids=getNumber(MED_ALL_ELEMENTS);
741 set<int> idsSet(ids,ids+getNumberOfElements(MED_ALL_ELEMENTS));
742 const int *idsMySupport=mySupport->getNumber(MED_ALL_ELEMENTS);
743 int mySupportSize=mySupport->getNumberOfElements(MED_ALL_ELEMENTS);
744 set<int> idsSetMySupport(idsMySupport,idsMySupport+mySupportSize);
745 set<int>::iterator iter;
747 for(iter=idsSet.begin();iter!=idsSet.end();iter++)
748 if(idsSetMySupport.find(*iter)!=idsSetMySupport.end())
749 idsList.push_back(*iter);
750 int size=idsSet.size();
751 int sizeList = idsList.size();
753 MESSAGE_MED(LOC << " size Set " << idsSet.size() << " size List " << idsList.size());
755 if(size!=0 && sizeList != 0)
757 if(_entity==MED_NODE)
758 fillFromNodeList(idsList);
760 fillFromElementList(idsList);
764 clearDataOnNumbers();
771 Method that cleans up all the fields related to _numbers. Defined for code factorization.
773 //--------------------------------------------------
774 void MEDMEM::SUPPORT::clearDataOnNumbers()
775 //--------------------------------------------------
777 _numberOfGeometricType=0;
778 _totalNumberOfElements=0;
783 _number=(MEDSKYLINEARRAY *) NULL;
788 operator == This operator does not compare attributs _name and _description.
790 //--------------------------------------------------
791 bool MEDMEM::SUPPORT::operator == (const SUPPORT &support) const
792 //--------------------------------------------------
795 const char* LOC = "bool SUPPORT::operator ==(const SUPPORT &support) const : ";
798 bool operatorReturn = false;
800 operatorReturn = (*_mesh == *support._mesh) && (_entity == support._entity) &&
801 (_numberOfGeometricType == support._numberOfGeometricType) &&
802 ((_isOnAllElts && support._isOnAllElts) || (!_isOnAllElts && !support._isOnAllElts)) &&
803 (_totalNumberOfElements == support._totalNumberOfElements) &&
804 (_profilNames.size() == support._profilNames.size());
810 for (int i=0; i<_numberOfGeometricType; i++)
812 operatorReturn = operatorReturn &&
813 (_geometricType[i] == support._geometricType[i]) &&
814 (_numberOfElements[i] == support._numberOfElements[i]);
818 for (int j=0; j<_numberOfElements[i]; j++)
820 operatorReturn = operatorReturn &&
821 (getNumber(_geometricType[i])[j] ==
822 support.getNumber(_geometricType[i])[j]);
831 return operatorReturn;
834 void SUPPORT::changeElementsNbs(MED_EN::medEntityMesh entity, const int *renumberingFromOldToNew, int limitNbClassicPoly, const int *renumberingFromOldToNewPoly)
836 if(entity != _entity)
837 throw MEDEXCEPTION("SUPPORT::changeElementsNbs : Renumbering on a mismatch entity");
841 const int *oldNbs=_number->getValue();
842 for(int i=0;i<_totalNumberOfElements;i++)
844 int globNb=oldNbs[i];
845 if(globNb<=limitNbClassicPoly)
846 newNbs.push_back(renumberingFromOldToNew[globNb-1]);
848 newNbs.push_back(renumberingFromOldToNewPoly[globNb-limitNbClassicPoly-1]);
851 fillFromElementList(newNbs);
858 operator == + in case false a test if coordinates and connectivity of _mesh and support->_mesh are the same
860 bool MEDMEM::SUPPORT::deepCompare(const SUPPORT &support) const
862 bool operatorReturn =(_entity == support._entity) &&
863 (_numberOfGeometricType == support._numberOfGeometricType) &&
864 ( (_isOnAllElts && support._isOnAllElts) || (!_isOnAllElts && !support._isOnAllElts) ) &&
865 (_totalNumberOfElements == support._totalNumberOfElements);
870 for (int i=0; i<_numberOfGeometricType && operatorReturn; i++)
872 operatorReturn = (_geometricType[i] == support._geometricType[i]) &&
873 (_numberOfElements[i] == support._numberOfElements[i]);
876 for (int j=0; j<_numberOfElements[i]; j++)
878 operatorReturn = (getNumber(_geometricType[i])[j] ==
879 support.getNumber(_geometricType[i])[j]);
887 if(!(*_mesh == *support._mesh))
889 return _mesh->deepCompare(*support._mesh);
892 return operatorReturn;
896 States if this is included in other.
898 bool MEDMEM::SUPPORT::belongsTo(const SUPPORT& other, bool deepCompare) const
900 if(!(*_mesh == *other._mesh))
904 if(!_mesh->deepCompare(*other._mesh))
907 if(_entity!=other._entity)
909 if(other._isOnAllElts)
911 if(_isOnAllElts && !other._isOnAllElts)
913 if(_numberOfGeometricType>other._numberOfGeometricType)
915 for(int i=0; i<_numberOfGeometricType; i++)
917 MED_EN::medGeometryElement curGeomType=_geometricType[i];
919 for(int j=0; j<other._numberOfGeometricType; j++)
920 if(other._geometricType[j]==curGeomType)
924 if(_numberOfElements[i]>other._numberOfElements[iOther])
926 const int *numbers1=_number->getI(i+1);
927 const int *numbers2=other._number->getI(iOther+1);
928 for (int k=0; k<_numberOfElements[i]; k++)
931 for(int l=0;l<other._numberOfElements[iOther] && !found;l++)
933 if(numbers1[k]==numbers2[l])
943 Method used to sort array of id.
945 int compareId(const void *x, const void *y)
947 const int *x1=(const int *)x;
948 const int *y1=(const int *)y;
958 performs a common operation : Sub builds a sorted int array that is obtained by supression of all ids contained
959 in array defined by (idsToSuppress,lgthIdsToSuppress) from array [start ... end]
960 Example sub(0,7,{1,2,5},3) => {0,3,4,6,7} - WARNING returned list should be deallocated !
962 list<int> *MEDMEM::SUPPORT::sub(int start,int end,const int *idsToSuppress,int lgthIdsToSuppress)
964 int size=end-start+1;
965 int sizeRet=size-lgthIdsToSuppress;
968 throw MEDEXCEPTION("MEDMEM::SUPPORT::sub");
976 for(int l=0;l<size;l++)
977 ret->push_back(start+l);
981 int *temp=new int[lgthIdsToSuppress+1];
982 memcpy(temp,idsToSuppress,sizeof(int)*lgthIdsToSuppress);
983 temp[lgthIdsToSuppress] = -1;
984 qsort(temp,lgthIdsToSuppress,sizeof(int),compareId);
986 for(int i=start;i<=end;i++)
996 performs a common operation : Sub builds a sorted int array that is obtained by supression of all ids contained
997 in array defined by (idsToSuppress,lgthIdsToSuppress) from array [start ... end]
998 Example sub({1,3,4,5,6,7,9},7,{1,2,5},3) => {3,4,6,7,9} - WARNING returned list should be deallocated !
1000 list<int> *MEDMEM::SUPPORT::sub(const int *ids,int lgthIds,const int *idsToSuppress,int lgthIdsToSuppress)
1005 throw MEDEXCEPTION("MEDMEM::SUPPORT::sub");
1009 int *temp1=new int[lgthIds];
1010 memcpy(temp1,ids,sizeof(int)*lgthIds);
1011 qsort(temp1,lgthIds,sizeof(int),compareId);
1012 int *temp2=new int[lgthIdsToSuppress];
1013 memcpy(temp2,idsToSuppress,sizeof(int)*lgthIdsToSuppress);
1014 qsort(temp2,lgthIdsToSuppress,sizeof(int),compareId);
1017 if(j>=lgthIdsToSuppress)
1018 ret->push_back(temp1[i++]);
1019 else if(temp1[i]>temp2[j])
1021 else if(temp1[i]<temp2[j])
1022 ret->push_back(temp1[i++]);
1032 returns a new SUPPORT (responsability to caller to destroy it)
1033 that is the complement to "this", lying on the same entity than "this".
1035 SUPPORT *MEDMEM::SUPPORT::getComplement() const
1038 const int nbOfElt=_mesh->getNumberOfElements(_entity,MED_EN::MED_ALL_ELEMENTS);
1039 int nbOfEltInSupp=getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
1040 if(_isOnAllElts || nbOfElt==nbOfEltInSupp)
1043 ret->setMesh(_mesh);
1044 ret->setEntity(_entity);
1045 string name="Complement of ";
1050 const int *nbs=_number->getValue();
1051 list<int> *ids=sub(1,nbOfElt,nbs,nbOfEltInSupp);
1052 if(_entity==MED_EN::MED_NODE)
1053 ret=_mesh->buildSupportOnNodeFromElementList(*ids,_entity);
1055 ret=_mesh->buildSupportOnElementsFromElementList(*ids,_entity);
1061 returns a new support the user should delete.
1063 SUPPORT *MEDMEM::SUPPORT::substract(const SUPPORT& other) const throw (MEDEXCEPTION)
1065 const char * LOC = "SUPPORT *MEDMEM::subtract(const SUPPORT * other) : ";
1068 if (_entity!=other.getEntity())
1069 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Entities are different !"));
1070 if(!(*_mesh == *other.getMesh()))
1071 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Mesh are different !"));
1072 if(other._isOnAllElts)
1075 ret->setMesh(_mesh);
1076 ret->setEntity(_entity);
1080 return other.getComplement();
1081 int nbOfEltInThis=getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
1082 const int *nbsThis=_number->getValue();
1083 int nbOfEltInOther=other.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
1084 const int *nbsOther=other._number->getValue();
1085 list<int> *ids=sub(nbsThis,nbOfEltInThis,nbsOther,nbOfEltInOther);
1086 if(_entity==MED_EN::MED_NODE)
1087 ret=_mesh->buildSupportOnNodeFromElementList(*ids,_entity);
1089 ret=_mesh->buildSupportOnElementsFromElementList(*ids,_entity);
1096 returns a new support the user has to delete. Entity is either MED_NODE to obtain node elements lying on boundary of "this"
1097 or MED_FACE,MED_EDGE (depends on the this->_mesh dimension).
1099 SUPPORT *MEDMEM::SUPPORT::getBoundaryElements(MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION)
1101 const char * LOC = "SUPPORT *MEDMEM::SUPPORT::getBoundaryElements(MED_EN::medEntityMesh Entity) : ";
1103 int spaceDimension=_mesh->getSpaceDimension();
1104 MED_EN::medEntityMesh baseEntity=Entity;
1105 if (spaceDimension == 3)
1106 if (Entity!=MED_FACE)
1107 if(Entity==MED_NODE)
1108 baseEntity=MED_FACE;
1110 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined in 3D mesh for entity "<<Entity<<" !"));
1111 if (spaceDimension == 2)
1112 if (Entity!=MED_EDGE)
1113 if(Entity==MED_NODE)
1114 baseEntity=MED_EDGE;
1116 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined in 2D mesh for entity "<<Entity<<" !"));
1118 return _mesh->getBoundaryElements(Entity);
1120 const int * myConnectivityValue=_mesh->getReverseConnectivity(MED_DESCENDING);
1121 const int * myConnectivityIndex=_mesh->getReverseConnectivityIndex(MED_DESCENDING);
1122 int numberOf=_mesh->getNumberOfElements(baseEntity,MED_ALL_ELEMENTS);
1123 const int *ids=_number->getValue();
1124 set<int> idsSet(ids,ids+_totalNumberOfElements);
1125 list<int> myElementsList;
1126 for (int i=0;i<numberOf;i++)
1128 int nbOfDP1EntitySharing=0;
1129 if(idsSet.find(myConnectivityValue[myConnectivityIndex[i]-1])!=idsSet.end())
1130 nbOfDP1EntitySharing++;
1131 if(idsSet.find(myConnectivityValue[myConnectivityIndex[i]])!=idsSet.end())
1132 nbOfDP1EntitySharing++;
1133 if(nbOfDP1EntitySharing==1)
1134 myElementsList.push_back(i+1);
1136 if(Entity==MED_NODE)
1138 return _mesh->buildSupportOnNodeFromElementList(myElementsList,baseEntity);
1142 return _mesh->buildSupportOnElementsFromElementList(myElementsList,baseEntity);
1147 Method that fills this and updates all its attributes in order to lye on the the listOfNode.
1149 void MEDMEM::SUPPORT::fillFromNodeList(const list<int>& listOfNode) throw (MEDEXCEPTION)
1151 setEntity(MED_EN::MED_NODE);
1152 clearDataOnNumbers();
1153 int size=listOfNode.size();
1154 int totalNbInMesh=_mesh->getNumberOfElements(_entity,MED_ALL_ELEMENTS);
1155 if(totalNbInMesh==size)
1163 int numberOfGeometricType=1;
1164 medGeometryElement* geometricType=new medGeometryElement[1];
1165 geometricType[0]=MED_NONE;
1166 int *numberOfElements=new int[1];
1167 numberOfElements[0]=size;
1168 int *mySkyLineArrayIndex=new int[2];
1169 mySkyLineArrayIndex[0]=1;
1170 mySkyLineArrayIndex[1]=1+numberOfElements[0];
1171 int *tab=new int[numberOfElements[0]];
1173 for(list<int>::const_iterator iter2=listOfNode.begin();iter2!=listOfNode.end();iter2++)
1175 MEDSKYLINEARRAY * mySkyLineArray = new MEDSKYLINEARRAY(1,numberOfElements[0],mySkyLineArrayIndex,tab,true);
1176 setNumberOfGeometricType(numberOfGeometricType);
1177 setGeometricType(geometricType);
1178 setNumberOfElements(numberOfElements);
1179 //setTotalNumberOfElements(numberOfElements[0]);
1180 setNumber(mySkyLineArray);
1182 delete[] numberOfElements;
1183 delete[] geometricType;
1187 Method created to factorize code. This method fills the current SUPPORT on entity 'entity' containing all the entities contained in
1188 elements 'listOfElt' of entity 'entity'. Warning this method should be called after both the attributes this->_mesh and this->_entity are correctly set.
1190 void MEDMEM::SUPPORT::fillFromElementList(const list<int>& listOfElt) throw (MEDEXCEPTION)
1192 clearDataOnNumbers();
1193 int size=listOfElt.size();
1194 int totalNbInMesh=_mesh->getNumberOfElementsWithPoly(_entity,MED_ALL_ELEMENTS);
1195 if(totalNbInMesh==size){
1202 // Well, we must know how many geometric type we have found
1203 int * myListArray = new int[size] ;
1205 list<int>::const_iterator myElementsListIt ;
1206 for (myElementsListIt=listOfElt.begin();myElementsListIt!=listOfElt.end();myElementsListIt++)
1207 myListArray[id++]=(*myElementsListIt) ;
1208 int numberOfGeometricType ;
1209 medGeometryElement* geometricType ;
1210 int * numberOfElements ;
1211 int * mySkyLineArrayIndex ;
1213 int numberOfType = _mesh->getNumberOfTypesWithPoly(_entity) ;
1214 if (numberOfType == 1) {
1215 numberOfGeometricType = 1 ;
1216 geometricType = new medGeometryElement[1] ;
1217 medGeometryElement * allType = _mesh->getTypesWithPoly(_entity);
1218 geometricType[0] = allType[0] ;
1219 numberOfElements = new int[1] ;
1220 numberOfElements[0] = size ;
1221 mySkyLineArrayIndex = new int[2] ;
1222 mySkyLineArrayIndex[0]=1 ;
1223 mySkyLineArrayIndex[1]=1+size ;
1227 map<medGeometryElement,int> theType ;
1228 for (myElementsListIt=listOfElt.begin();myElementsListIt!=listOfElt.end();myElementsListIt++) {
1229 medGeometryElement myType = _mesh->getElementTypeWithPoly(_entity,*myElementsListIt) ;
1230 if (theType.find(myType) != theType.end() )
1231 theType[myType]+=1 ;
1235 numberOfGeometricType = theType.size() ;
1236 geometricType = new medGeometryElement[numberOfGeometricType] ;
1237 numberOfElements = new int[numberOfGeometricType] ;
1238 mySkyLineArrayIndex = new int[numberOfGeometricType+1] ;
1240 mySkyLineArrayIndex[0]=1 ;
1241 map<medGeometryElement,int>::iterator theTypeIt ;
1242 for (theTypeIt=theType.begin();theTypeIt!=theType.end();theTypeIt++) {
1243 geometricType[index] = (*theTypeIt).first ;
1244 numberOfElements[index] = (*theTypeIt).second ;
1245 mySkyLineArrayIndex[index+1]=mySkyLineArrayIndex[index]+numberOfElements[index] ;
1249 MEDSKYLINEARRAY * mySkyLineArray = new MEDSKYLINEARRAY(numberOfGeometricType,size,mySkyLineArrayIndex,myListArray,true) ;
1250 setNumberOfGeometricType(numberOfGeometricType) ;
1251 setGeometricType(geometricType) ;
1252 setNumberOfElements(numberOfElements) ;
1253 //setTotalNumberOfElements(size) ;
1254 setNumber(mySkyLineArray) ;
1256 delete[] numberOfElements;
1257 delete[] geometricType;
1260 /*! set the reference _mesh to Mesh */
1261 //--------------------------------------
1262 void SUPPORT::setMesh(MESH *Mesh) const
1263 //--------------------------------------
1266 _mesh->removeReference();
1270 _mesh->addReference();
1273 /*! returns the mesh name */
1274 //------------------------------------
1275 string SUPPORT::getMeshName() const
1276 //------------------------------------
1279 return _mesh->getName();
1285 addReference : reference counter presently disconnected in C++ -> just connected for client.
1287 void MEDMEM::SUPPORT::addReference() const
1292 removeReference : reference counter presently disconnected in C++ -> just connected for client.
1294 void MEDMEM::SUPPORT::removeReference() const