Back to index

salome-med  6.5.0
MEDMEM_Family.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 /*
00024  File MEDMEM_Family.cxx
00025 */
00026 
00027 #include "MEDMEM_Mesh.hxx"
00028 #include "MEDMEM_Family.hxx"
00029 
00030 using namespace std;
00031 using namespace MEDMEM;
00032 using namespace MED_EN;
00033 
00034 /*
00035   Those defines are from the med File V2.1 and for this class they are fixed.
00036 */
00037 
00038 #define MED_TAILLE_DESC 200
00039 #define MED_TAILLE_LNOM  80
00040 
00041 FAMILY::FAMILY():_identifier(0), _numberOfAttribute(0), _numberOfGroup(0)
00042 {
00043     MESSAGE_MED("FAMILY::FAMILY()");
00044 }
00045 
00046 FAMILY::FAMILY(GMESH* Mesh, int Identifier, string Name, int NumberOfAttribute,
00047                int *AttributeIdentifier, int *AttributeValue, string AttributeDescription,
00048                int NumberOfGroup, string GroupName,
00049                int * MEDArrayNodeFamily,
00050                int ** MEDArrayCellFamily,
00051                int ** MEDArrayFaceFamily,
00052                int ** MEDArrayEdgeFamily
00053                ): SUPPORT(),
00054                   _identifier(Identifier),
00055                   _numberOfAttribute(NumberOfAttribute),
00056                   _numberOfGroup(NumberOfGroup)
00057 {
00058   MESSAGE_MED("FAMILY(int Identifier, string Name, int NumberOfAttribute,int *AttributeIdentifier,int *AttributeValue,string AttributeDescription,int NumberOfGroup,string GroupName, int ** Number) : "<<Identifier);
00059 
00060   setMesh( Mesh );
00061   setName( Name );
00062   _isOnAllElts = false ;
00063   SCRUTE_MED(_numberOfAttribute);
00064   if (_numberOfAttribute > 0)
00065     {
00066       _attributeIdentifier.set(_numberOfAttribute,AttributeIdentifier);
00067       _attributeValue.set(_numberOfAttribute,AttributeValue);
00068 
00069       _attributeDescription.resize(_numberOfAttribute);
00070       for (int i=0;i<NumberOfAttribute;i++) {
00071         _attributeDescription[i].assign(AttributeDescription,i*MED_TAILLE_DESC,MED_TAILLE_DESC);
00072         _attributeDescription[i].erase(strlen(_attributeDescription[i].c_str()));
00073       }
00074     }
00075   else
00076     {
00077       _attributeIdentifier.set(_numberOfAttribute);
00078       _attributeValue.set(_numberOfAttribute);
00079       _attributeDescription.resize(_numberOfAttribute);
00080     }
00081 
00082   _groupName.resize(_numberOfGroup);
00083   for (int i=0;i<NumberOfGroup;i++)
00084     {
00085       _groupName[i].assign(GroupName,i*MED_TAILLE_LNOM,MED_TAILLE_LNOM);
00086       _groupName[i].erase(strlen(_groupName[i].c_str()));
00087     }
00088 
00089   // well, we must set SUPPORT attribut
00090   _description = "FAMILY" ;
00091   // on which geometric type :
00092   bool Find = false ;
00093 
00094 
00095   // ************************ NODES RELATED PART *************************************************
00096   // Scan every node family number <NodeFamilyNumber[i]> in order to create 
00097   // the list <tmp_NodesList> of node numbers <i+1> belonging to the family <_identifier>
00098   int NumberOfNodes         = _mesh->getNumberOfNodes();
00099   int NumberOfNodesInFamily = 0 ;
00100   int * tmp_NodesList       = new int[NumberOfNodes] ; // Un peu brutal...., oui mais ce n'est qu'un tableau de travail !
00101   for (int i=0; i<NumberOfNodes; i++)
00102     if ( _identifier == MEDArrayNodeFamily[i] )
00103       {
00104         tmp_NodesList[NumberOfNodesInFamily]=i+1 ;
00105         NumberOfNodesInFamily++;
00106       }
00107 
00108   SCRUTE_MED(NumberOfNodesInFamily);
00109 
00110   // If we found nodes, set the family attributes adequatly
00111   if (NumberOfNodesInFamily>0)
00112     {
00113       Find = true ;
00114     
00115       _entity = MED_NODE ;
00116     
00117     // family on all NODE
00118       if (NumberOfNodesInFamily==NumberOfNodes)
00119         {
00120           _isOnAllElts = true ;
00121           update();
00122         }
00123       else
00124         {
00125           _numberOfGeometricType = 1 ;
00126 
00127           _geometricType.set(1) ;
00128 
00129           _geometricType[0]=MED_NONE ;
00130           _isOnAllElts= false ;
00131 
00132           _numberOfElements.set(1) ;
00133 
00134           _numberOfElements[0]=NumberOfNodesInFamily ;
00135           _totalNumberOfElements=NumberOfNodesInFamily;
00136 
00137           int * NumberIndex = new int[2];
00138           int * NumberValue = new int[NumberOfNodesInFamily];
00139 
00140           NumberIndex[0]=1;                          //set the MEDSKYLINEARRAY Index table
00141           NumberIndex[1]=1+NumberOfNodesInFamily;    //set the MEDSKYLINEARRAY Index table
00142           for(int i=0; i<NumberOfNodesInFamily; i++) // OH LA LA... 
00143             NumberValue[i]=tmp_NodesList[i] ;        // RESIZE de tmp_NodesList serait plus efficace !!!!!!!!
00144           setNumber( new MEDSKYLINEARRAY(1,NumberOfNodesInFamily,NumberIndex,NumberValue));
00145           delete[] NumberIndex ;
00146           delete[] NumberValue ;
00147         }
00148     }
00149   delete[] tmp_NodesList ;
00150   
00151 
00152 
00153   // ************************ CELLS RELATED PART *************************************************
00154   // If we previously found nodes in our family don't scan the CELLS because a
00155   // family contains different geometic types of only one entity type.
00156   // ?? Scan every cell family number <NodeFamilyNumber[i]> in order to create 
00157   // ?? the list <tmp_NodesList> of node numbers <i+1> belonging to the family <_identifier>
00158   if (!Find)
00159     {
00160       Find = build(MED_CELL,MEDArrayCellFamily) ;
00161     }
00162   // on face ?
00163   if (!Find)
00164     {
00165       if ( _mesh->getNumberOfElements(MED_FACE, MED_ALL_ELEMENTS) > 0 )
00166         Find = build(MED_FACE,MEDArrayFaceFamily) ;
00167     }
00168 
00169   // on edge ?
00170   if (!Find)
00171     {
00172       if ( _mesh->getNumberOfElements(MED_EDGE, MED_ALL_ELEMENTS) > 0 )
00173         Find = build(MED_EDGE,MEDArrayEdgeFamily) ;
00174     }
00175   // That's all !
00176 
00177   // if not find : no entity in familly !!!
00178   if (!Find)
00179     {
00180       _numberOfGeometricType = 0 ;
00181       _isOnAllElts = false ;
00182       MESSAGE_MED ("FAMILY() : No entity found !") ;
00183     }
00184 
00185   MESSAGE_MED("Well now ??? :::");
00186 
00187   MESSAGE_MED("Name : "<< getName());
00188   MESSAGE_MED("Description : "<< getDescription());
00189   MESSAGE_MED("Mesh name : " << getMesh()->getName());
00190   MESSAGE_MED("Entity : "<< getEntity());
00191   MESSAGE_MED("Entity list :");
00192   if ( !isOnAllElements() )
00193     {
00194       MESSAGE_MED("NumberOfTypes : "<<getNumberOfTypes());
00195       for (int j=0;j<getNumberOfTypes();j++)
00196         {
00197           MESSAGE_MED("    * Type "<<getTypes()[j]<<" : there is(are) "<<
00198                       getNumberOfElements(getTypes()[j])<<" element(s) : ");
00199           SCRUTE_MED(getNumber(getTypes()[j]));
00200         }
00201     }
00202   else
00203     {
00204       MESSAGE_MED("Is on all entities !");
00205     }
00206 }
00207 
00208 FAMILY::FAMILY(const FAMILY & m):SUPPORT(m)
00209 {
00210   MESSAGE_MED("FAMILY::FAMILY(FAMILY & m)");
00211   _identifier = m._identifier;
00212   _numberOfAttribute = m._numberOfAttribute;
00213 
00214   if (_numberOfAttribute)
00215     {
00216       _attributeIdentifier.set(_numberOfAttribute,m._attributeIdentifier);
00217       _attributeValue.set(_numberOfAttribute,m._attributeValue);
00218     }
00219 
00220   _attributeDescription.resize(_numberOfAttribute);
00221   for (int i=0;i<m._numberOfAttribute;i++)
00222     _attributeDescription[i] = m._attributeDescription[i];
00223 
00224   _numberOfGroup = m._numberOfGroup;
00225 
00226   _groupName.resize(_numberOfGroup) ;
00227   for (int i=0;i<m._numberOfGroup;i++)
00228     _groupName[i]=m._groupName[i];
00229 }
00230 
00231 FAMILY::FAMILY(const SUPPORT & s):SUPPORT(s)
00232 {
00233   MESSAGE_MED("FAMILY::FAMILY(const SUPPORT & s)");
00234 
00235   _identifier = 0;
00236   _numberOfAttribute = 0;
00237 
00238   _numberOfGroup = 0;
00239 }
00240 
00241 FAMILY::~FAMILY()
00242 {
00243   MESSAGE_MED("~FAMILY()");
00244 }
00245 
00246 FAMILY & FAMILY::operator=(const FAMILY &fam) 
00247 {
00248   MESSAGE_MED("FAMILY::operator=");
00249   if ( this == &fam ) return *this;
00250 
00251   //Etant donné que l'opérateur d'affectation de la classe SUPPORT effectuait
00252   //une recopie profonde j'ai mis en cohérence l'opérateur d'affectation
00253   // de la classe FAMILY
00254   SUPPORT::operator=(fam);
00255 
00256 
00257   _identifier = fam._identifier;
00258   _numberOfAttribute = fam._numberOfAttribute; 
00259   _attributeIdentifier.set(_numberOfAttribute, fam._attributeIdentifier) ;
00260   _attributeValue.set(_numberOfAttribute, fam._attributeValue) ;
00261   _attributeDescription.clear();
00262   _attributeDescription = fam._attributeDescription;
00263   _numberOfGroup = fam._numberOfGroup;
00264   _groupName.clear();
00265   _groupName = fam._groupName;
00266   return *this;
00267 }
00268 
00269 ostream & MEDMEM::operator<<(ostream &os, FAMILY &myFamily)
00270 {
00271   // how do cast without duplicate ?
00272   os << (SUPPORT&) myFamily;
00273 
00274   os << "  - Identifier : "<<myFamily.getIdentifier()<<endl;
00275   int numberofattributes = myFamily.getNumberOfAttributes();
00276   os << "  - Attributes ("<<numberofattributes<<") :"<<endl;
00277   for (int j=1;j<numberofattributes+1;j++)
00278     os << "    * "<<myFamily.getAttributeIdentifier(j)<<" : "<<myFamily.getAttributeValue(j)<<", "<<myFamily.getAttributeDescription(j).c_str()<<endl;
00279   int numberofgroups = myFamily.getNumberOfGroups();
00280   os << "  - Groups ("<<numberofgroups<<") :"<<endl;
00281   for (int j=1;j<numberofgroups+1;j++)
00282     os << "    * "<<myFamily.getGroupName(j).c_str()<<endl ;
00283 
00284   return os;
00285 }
00286 
00287 ostream & MEDMEM::operator<<(ostream &os, const FAMILY &myFamily)
00288 {
00289   // how do cast without duplicate ?
00290   os << (const SUPPORT&) myFamily;
00291 
00292   os << "  - Identifier : "<<myFamily.getIdentifier()<<endl;
00293   int numberofattributes = myFamily.getNumberOfAttributes();
00294   os << "  - Attributes ("<<numberofattributes<<") :"<<endl;
00295   for (int j=1;j<numberofattributes+1;j++)
00296     os << "    * "<<myFamily.getAttributeIdentifier(j)<<" : "<<myFamily.getAttributeValue(j)<<", "<<myFamily.getAttributeDescription(j).c_str()<<endl;
00297   int numberofgroups = myFamily.getNumberOfGroups();
00298   os << "  - Groups ("<<numberofgroups<<") :"<<endl;
00299   for (int j=1;j<numberofgroups+1;j++)
00300     os << "    * "<<myFamily.getGroupName(j).c_str()<<endl ;
00301 
00302   return os;
00303 }
00304 
00305 bool FAMILY::build(medEntityMesh Entity,int **FamilyNumber /* from MED file */)
00306 {
00307   MESSAGE_MED("FAMILY::build(medEntityMesh Entity,int **FamilyNumber /* from MED file */)");
00308   bool Find = false ;
00309   // Get types information from <_mesh>
00310   int    numberOfTypes             = _mesh->getNumberOfTypes(Entity) ;
00311   const medGeometryElement * types = _mesh->getTypes(Entity) ;
00312   
00313   int *  numberOfElementsInFamily     = new int[numberOfTypes] ;
00314   int    numberOfElementTypesInFamily = 0 ;
00315 
00316   medGeometryElement * tmp_Types    = new medGeometryElement[numberOfTypes];
00317   int ** tmp_ElementsLists          = new int*[numberOfTypes] ;
00318   int elementNumber                 = 1;
00319   
00320 
00321   SCRUTE_MED(numberOfTypes);
00322 
00323   // we search for all elements in this family
00324   for (int TypeNumber=0; TypeNumber < numberOfTypes; TypeNumber++) {
00325     
00326     int NumberOfElements             = _mesh->getNumberOfElements(Entity,types[TypeNumber]) ;
00327     int NumberOfElementsInThisFamily = 0 ;
00328     int * ElementsOfThisFamilyNumber = FamilyNumber[TypeNumber];
00329     int * tmp_ElementsList           = new int[NumberOfElements];
00330 
00331     for (int i=0; i<NumberOfElements; i++, elementNumber++)
00332       {
00333         if (_identifier == ElementsOfThisFamilyNumber[i]) {
00334           tmp_ElementsList[NumberOfElementsInThisFamily]=elementNumber;
00335           NumberOfElementsInThisFamily++;
00336         }
00337       }
00338     
00339     if (NumberOfElementsInThisFamily>0) {// we have found some elements
00340       numberOfElementsInFamily[numberOfElementTypesInFamily]=NumberOfElementsInThisFamily;
00341 
00342       int * ElementsList = new int[NumberOfElementsInThisFamily] ;
00343       memcpy(ElementsList,tmp_ElementsList,sizeof(int)*NumberOfElementsInThisFamily); // RESIZE de tmp_NodesList serait plus efficace !!!!!!!!
00344         
00345       tmp_ElementsLists[numberOfElementTypesInFamily]=ElementsList ;
00346       tmp_Types[numberOfElementTypesInFamily]=types[TypeNumber];
00347       numberOfElementTypesInFamily++;
00348     }
00349     delete[] tmp_ElementsList;
00350   }
00351 
00352   // we define all attribut in SUPPORT :
00353   if (numberOfElementTypesInFamily>0) // we have found elements
00354     {
00355       Find = true ;
00356       _entity = Entity ;
00357       _numberOfGeometricType = numberOfElementTypesInFamily ;
00358       _geometricType.set(numberOfElementTypesInFamily) ;
00359 
00360       _isOnAllElts = false ;
00361 
00362       _numberOfElements.set(numberOfElementTypesInFamily) ;
00363       _totalNumberOfElements=0;
00364 
00365       for (int i=0; i<numberOfElementTypesInFamily; i++)
00366         {
00367           _geometricType[i]=tmp_Types[i] ;
00368           _numberOfElements[i]=numberOfElementsInFamily[i]; // plutot un resize !!
00369           _totalNumberOfElements+=_numberOfElements[i];
00370         }
00371 
00372       // family on all ELEMENT ?
00373       if (Entity == MED_EN::MED_CELL &&
00374           _totalNumberOfElements ==_mesh->getNumberOfElements(Entity,MED_ALL_ELEMENTS))
00375         {
00376           _isOnAllElts = true ;
00377           update();
00378           // all others attributs are rights !
00379           for (int i=0; i<_numberOfGeometricType; i++)
00380             delete[] tmp_ElementsLists[i];
00381         }
00382       else
00383         {
00384           int *NumberValue = new int[_totalNumberOfElements];
00385           int *NumberIndex = new int[_numberOfGeometricType+1];
00386           NumberIndex[0]=1;
00387           for (int i=0; i<_numberOfGeometricType; i++)
00388             {
00389               NumberIndex[i+1]=NumberIndex[i]+_numberOfElements[i];
00390               for (int j=NumberIndex[i]; j<NumberIndex[i+1]; j++)
00391                 NumberValue[j-1]=tmp_ElementsLists[i][j-NumberIndex[i]];
00392               delete[] tmp_ElementsLists[i];
00393             }
00394           setNumber( new MEDSKYLINEARRAY(_numberOfGeometricType, _totalNumberOfElements,
00395                                          NumberIndex, NumberValue));
00396           delete[] NumberIndex ;
00397           delete[] NumberValue ;
00398         }
00399     }
00400   delete[] tmp_Types;
00401   delete[] numberOfElementsInFamily;
00402 
00403   delete[] tmp_ElementsLists;
00404 
00405   return Find ;
00406 }
00407