Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/med.git] / src / MEDMEM / MEDMEM_Family.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 /*
23  File MEDMEM_Family.cxx
24  $Header$
25 */
26
27 #include "MEDMEM_Mesh.hxx"
28 #include "MEDMEM_Family.hxx"
29
30 using namespace std;
31 using namespace MEDMEM;
32 using namespace MED_EN;
33
34 /*
35   Those defines are from the med File V2.1 and for this class they are fixed.
36 */
37
38 #define MED_TAILLE_DESC 200
39 #define MED_TAILLE_LNOM  80
40
41 FAMILY::FAMILY():_identifier(0), _numberOfAttribute(0), _numberOfGroup(0)
42 {
43     MESSAGE_MED("FAMILY::FAMILY()");
44 }
45
46 FAMILY::FAMILY(MESH* Mesh, int Identifier, string Name, int NumberOfAttribute,
47                int *AttributeIdentifier, int *AttributeValue, string AttributeDescription,
48                int NumberOfGroup, string GroupName,
49                int * MEDArrayNodeFamily,
50                int ** MEDArrayCellFamily,
51                int ** MEDArrayFaceFamily,
52                int ** MEDArrayEdgeFamily
53                ): SUPPORT(Mesh,Name),
54                   _identifier(Identifier), 
55                   _numberOfAttribute(NumberOfAttribute), 
56                   _numberOfGroup(NumberOfGroup)
57 {
58   MESSAGE_MED("FAMILY(int Identifier, string Name, int NumberOfAttribute,int *AttributeIdentifier,int *AttributeValue,string AttributeDescription,int NumberOfGroup,string GroupName, int ** Number) : "<<Identifier);
59
60   _isOnAllElts = false ;
61   SCRUTE_MED(_numberOfAttribute);
62   if (_numberOfAttribute > 0)
63     {
64       _attributeIdentifier.set(_numberOfAttribute,AttributeIdentifier);
65       _attributeValue.set(_numberOfAttribute,AttributeValue);
66
67       //_attributeDescription.set(_numberOfAttribute);
68       _attributeDescription.resize(_numberOfAttribute);
69       for (int i=0;i<NumberOfAttribute;i++) {
70         _attributeDescription[i].assign(AttributeDescription,i*MED_TAILLE_DESC,MED_TAILLE_DESC);
71         _attributeDescription[i].erase(strlen(_attributeDescription[i].c_str()));
72         //SCRUTE_MED(_attributeDescription[i]);
73       }
74     }
75   else
76     {
77       _attributeIdentifier.set(_numberOfAttribute);
78       _attributeValue.set(_numberOfAttribute);
79       //_attributeDescription.set(_numberOfAttribute);
80       _attributeDescription.resize(_numberOfAttribute);
81     }
82  
83   //_groupName.set(_numberOfGroup);
84   _groupName.resize(_numberOfGroup);
85   for (int i=0;i<NumberOfGroup;i++) {
86     _groupName[i].assign(GroupName,i*MED_TAILLE_LNOM,MED_TAILLE_LNOM);
87     _groupName[i].erase(strlen(_groupName[i].c_str()));
88     //SCRUTE_MED(_groupName[i]);
89   }
90
91   // well, we must set SUPPORT attribut
92   _description = "FAMILY" ;
93   // on which geometric type :
94   bool Find = false ;
95   
96
97   // ************************ NODES RELATED PART *************************************************
98   // Scan every node family number <NodeFamilyNumber[i]> in order to create 
99   // the list <tmp_NodesList> of node numbers <i+1> belonging to the family <_identifier>
100   int NumberOfNodes         = _mesh->getNumberOfNodes();
101   int NumberOfNodesInFamily = 0 ;
102   //int * NodeFamilyNumber    = _mesh->getMEDArrayNodeFamily() ;   // EF : TEMPORAIRE !!
103   int * tmp_NodesList       = new int[NumberOfNodes] ;           // Un peu brutal...., oui mais ce n'est qu'un tableau de travail !
104   for (int i=0; i<NumberOfNodes; i++)
105     if ( _identifier == MEDArrayNodeFamily[i] ) {
106       tmp_NodesList[NumberOfNodesInFamily]=i+1 ;
107       NumberOfNodesInFamily++;
108     }
109
110   SCRUTE_MED(NumberOfNodesInFamily);
111
112   // If we found nodes set the family attributes adequatly
113   if (NumberOfNodesInFamily>0) {
114     
115     Find = true ;
116     
117     _entity = MED_NODE ;
118 //      _numberOfGeometricType = 1 ;
119 //      _geometricType = new medGeometryElement[1] ;
120 //      _geometricType[0]=MED_NONE ;
121     
122     // family on all NODE
123     if (NumberOfNodesInFamily==NumberOfNodes) {
124       _isOnAllElts = true ;
125       update();
126     } else {
127       _numberOfGeometricType = 1 ;
128
129       _geometricType.set(1) ;
130
131       _geometricType[0]=MED_NONE ;
132       _isOnAllElts= false ;
133
134       _numberOfElements.set(1) ;
135
136       _numberOfElements[0]=NumberOfNodesInFamily ;
137       _totalNumberOfElements=NumberOfNodesInFamily;
138       
139 //        _number=new MEDSKYLINEARRAY(1,NumberOfNodesInFamily) ;
140 //        int * NumberIndex = _number->getIndex();
141 //        int * NumberValue = _number->getValue();
142       int * NumberIndex = new int[2];
143       int * NumberValue = new int[NumberOfNodesInFamily];
144
145       NumberIndex[0]=1;                          //set the MEDSKYLINEARRAY Index table
146       NumberIndex[1]=1+NumberOfNodesInFamily;    //set the MEDSKYLINEARRAY Index table
147       for(int i=0; i<NumberOfNodesInFamily; i++) // OH LA LA... 
148         NumberValue[i]=tmp_NodesList[i] ;        // RESIZE de tmp_NodesList serait plus efficace !!!!!!!!
149       // PG : pas de problème, si ca marche. Il faudra déplacer le delete !
150       if(_number!=NULL) delete _number ;
151       _number=new MEDSKYLINEARRAY(1,NumberOfNodesInFamily,NumberIndex,NumberValue) ;
152       delete[] NumberIndex ;
153       delete[] NumberValue ;
154     }
155   }
156   delete[] tmp_NodesList ;
157   
158
159
160   // ************************ CELLS RELATED PART *************************************************
161   // If we previously found nodes in our family don't scan the CELLS because a
162   // family contains different geometic types of only one entity type.
163   // ?? Scan every cell family number <NodeFamilyNumber[i]> in order to create 
164   // ?? the list <tmp_NodesList> of node numbers <i+1> belonging to the family <_identifier>
165   if (!Find) {
166     Find = build(MED_CELL,MEDArrayCellFamily) ;
167   }
168   // on face ?
169   if (!Find) {
170     if ((_mesh->existConnectivityWithPoly(MED_NODAL,MED_FACE)) |
171         (_mesh->existConnectivityWithPoly(MED_DESCENDING,MED_FACE))) {
172       Find = build(MED_FACE,MEDArrayFaceFamily) ;
173     }
174   }
175
176   // on edge ?
177   if (!Find) {
178     if ((_mesh->existConnectivity(MED_NODAL,MED_EDGE))|(_mesh->existConnectivity(MED_DESCENDING,MED_EDGE))) {
179       Find = build(MED_EDGE,MEDArrayEdgeFamily) ;
180     }
181   }
182   // That's all !
183
184   // if not find : no entity in familly !!!
185   if (!Find) {
186     _numberOfGeometricType = 0 ;
187     _isOnAllElts = false ;
188     MESSAGE_MED ("FAMILY() : No entity found !") ;
189   }
190
191   MESSAGE_MED("Well now ??? :::");
192
193   MESSAGE_MED("Name : "<< getName());
194   MESSAGE_MED("Description : "<< getDescription());
195   MESSAGE_MED("Mesh name : " << getMesh()->getName());
196   MESSAGE_MED("Entity : "<< getEntity());
197   MESSAGE_MED("Entity list :");
198   if (!(isOnAllElements())) {
199     MESSAGE_MED("NumberOfTypes : "<<getNumberOfTypes());
200     for (int j=0;j<getNumberOfTypes();j++) {
201       MESSAGE_MED("    * Type "<<getTypes()[j]<<" : there is(are) "<<
202                   getNumberOfElements(getTypes()[j])<<" element(s) : ");
203       SCRUTE_MED(getNumber(getTypes()[j]));
204       //      for (int k=0; k<numberOfElements;k++)
205         //      MESSAGE_MED("________________ " << number[k]);
206     }
207   }
208   else
209   {
210     MESSAGE_MED("Is on all entities !");
211   }
212
213
214 }
215
216 FAMILY::FAMILY(const FAMILY & m):SUPPORT(m)
217 {
218   MESSAGE_MED("FAMILY::FAMILY(FAMILY & m)");
219   _identifier = m._identifier;
220   _numberOfAttribute = m._numberOfAttribute;
221
222   if (_numberOfAttribute) {
223     _attributeIdentifier.set(_numberOfAttribute,m._attributeIdentifier);
224     _attributeValue.set(_numberOfAttribute,m._attributeValue);
225   }
226
227   //_attributeDescription.set(_numberOfAttribute);
228   _attributeDescription.resize(_numberOfAttribute);
229   for (int i=0;i<m._numberOfAttribute;i++)
230     _attributeDescription[i] = m._attributeDescription[i];
231
232   _numberOfGroup = m._numberOfGroup;
233
234   //_groupName.set(_numberOfGroup) ;
235   _groupName.resize(_numberOfGroup) ;
236   for (int i=0;i<m._numberOfGroup;i++)
237     _groupName[i]=m._groupName[i];
238 }
239
240 FAMILY::FAMILY(const SUPPORT & s):SUPPORT(s)
241 {
242   MESSAGE_MED("FAMILY::FAMILY(const SUPPORT & s)");
243
244   _identifier = 0;
245   _numberOfAttribute = 0;
246
247   _numberOfGroup = 0;
248 }
249
250 FAMILY::~FAMILY() 
251 {
252     MESSAGE_MED("~FAMILY()");
253 }
254   
255 FAMILY & FAMILY::operator=(const FAMILY &fam) 
256 {
257     MESSAGE_MED("FAMILY::operator=");
258     if ( this == &fam ) return *this;
259
260     //Etant donné que l'opérateur d'affectation de la classe SUPPORT effectuait
261     //une recopie profonde j'ai mis en cohérence l'opérateur d'affectation
262     // de la classe FAMILY
263     SUPPORT::operator=(fam);
264  
265
266     _identifier = fam._identifier;
267     _numberOfAttribute = fam._numberOfAttribute; 
268     _attributeIdentifier.set(_numberOfAttribute, fam._attributeIdentifier) ;
269     _attributeValue.set(_numberOfAttribute, fam._attributeValue) ;
270     //_attributeDescription.set(_numberOfAttribute, fam._attributeDescription) ;
271     _attributeDescription.clear();
272     _attributeDescription = fam._attributeDescription;
273     _numberOfGroup = fam._numberOfGroup;
274     //_groupName.set(_numberOfGroup, fam._groupName) ;
275     _groupName.clear();
276     _groupName = fam._groupName;
277     return *this;
278 }
279
280 ostream & MEDMEM::operator<<(ostream &os, FAMILY &myFamily)
281 {
282   // how do cast without duplicate ?
283   os << (SUPPORT) myFamily;
284
285   os << "  - Identifier : "<<myFamily.getIdentifier()<<endl;
286   int numberofattributes = myFamily.getNumberOfAttributes();
287   os << "  - Attributes ("<<numberofattributes<<") :"<<endl;
288   for (int j=1;j<numberofattributes+1;j++)
289     os << "    * "<<myFamily.getAttributeIdentifier(j)<<" : "<<myFamily.getAttributeValue(j)<<", "<<myFamily.getAttributeDescription(j).c_str()<<endl;
290   int numberofgroups = myFamily.getNumberOfGroups();
291   os << "  - Groups ("<<numberofgroups<<") :"<<endl;
292   for (int j=1;j<numberofgroups+1;j++)
293     os << "    * "<<myFamily.getGroupName(j).c_str()<<endl ;
294
295   return os;
296 }
297
298 ostream & MEDMEM::operator<<(ostream &os, const FAMILY &myFamily)
299 {
300   // how do cast without duplicate ?
301   os << (SUPPORT) myFamily;
302
303   os << "  - Identifier : "<<myFamily.getIdentifier()<<endl;
304   int numberofattributes = myFamily.getNumberOfAttributes();
305   os << "  - Attributes ("<<numberofattributes<<") :"<<endl;
306   for (int j=1;j<numberofattributes+1;j++)
307     os << "    * "<<myFamily.getAttributeIdentifier(j)<<" : "<<myFamily.getAttributeValue(j)<<", "<<myFamily.getAttributeDescription(j).c_str()<<endl;
308   int numberofgroups = myFamily.getNumberOfGroups();
309   os << "  - Groups ("<<numberofgroups<<") :"<<endl;
310   for (int j=1;j<numberofgroups+1;j++)
311     os << "    * "<<myFamily.getGroupName(j).c_str()<<endl ;
312
313   return os;
314 }
315
316 bool FAMILY::build(medEntityMesh Entity,int **FamilyNumber /* from MED file */)
317 {
318   MESSAGE_MED("FAMILY::build(medEntityMesh Entity,int **FamilyNumber /* from MED file */)");
319   bool Find = false ;
320   // Get types information from <_mesh>
321   int    numberOfTypes             = _mesh->getNumberOfTypesWithPoly(Entity) ;
322   medGeometryElement * types       = _mesh->getTypesWithPoly(Entity) ;
323   
324   int *  numberOfElementsInFamily         = new int[numberOfTypes] ;
325   int    numberOfElementTypesInFamily     = 0 ;
326   
327   medGeometryElement * tmp_Types  = new medGeometryElement[numberOfTypes];
328   int ** tmp_ElementsLists                = new int*[numberOfTypes] ;
329   //  int *  GeometricTypeNumber           = new int[numberOfTypes] ;
330   const int *  GlobalNumberingIndex          = _mesh->getGlobalNumberingIndex(Entity);
331   
332
333   SCRUTE_MED(numberOfTypes);
334
335   // we search for all elements in this family
336   for (int TypeNumber=0; TypeNumber < numberOfTypes; TypeNumber++) {
337     
338     int NumberOfElements             = _mesh->getNumberOfElementsWithPoly(Entity,types[TypeNumber]) ;
339     int NumberOfElementsInThisFamily = 0 ;
340     int * ElementsOfThisFamilyNumber = FamilyNumber[TypeNumber];
341     int * tmp_ElementsList           = new int[NumberOfElements];
342       
343     for (int i=0; i<NumberOfElements; i++)
344       {
345         //      SCRUTE_MED(ElementsOfThisFamilyNumber[i]);
346         if (_identifier == ElementsOfThisFamilyNumber[i]) {
347           tmp_ElementsList[NumberOfElementsInThisFamily]=i+GlobalNumberingIndex[TypeNumber] ;
348           NumberOfElementsInThisFamily++;
349         }
350       }
351     
352     if (NumberOfElementsInThisFamily>0) {// we have found some elements
353       numberOfElementsInFamily[numberOfElementTypesInFamily]=NumberOfElementsInThisFamily;
354
355       //int * ElementsList = tmp_ElementsList.resize(NumberOfElementsInThisFamily);
356       int * ElementsList = new int[NumberOfElementsInThisFamily] ;
357       memcpy(ElementsList,tmp_ElementsList,sizeof(int)*NumberOfElementsInThisFamily); // RESIZE de tmp_NodesList serait plus efficace !!!!!!!!
358         
359       tmp_ElementsLists[numberOfElementTypesInFamily]=ElementsList ;
360       tmp_Types[numberOfElementTypesInFamily]=types[TypeNumber];
361       //      GeometricTypeNumber[numberOfElementTypesInFamily]=TypeNumber+1;
362       numberOfElementTypesInFamily++;
363       //      delete [] ElementsList;
364     }
365     delete[] tmp_ElementsList;
366   }
367   
368   // we define all attribut in SUPPORT :
369   if (numberOfElementTypesInFamily>0) { // we have found elements
370     Find = true ;
371     _entity = Entity ;
372     _numberOfGeometricType = numberOfElementTypesInFamily ;
373     _geometricType.set(numberOfElementTypesInFamily) ;
374
375     _isOnAllElts = false ;
376
377     _numberOfElements.set(numberOfElementTypesInFamily) ;
378     _totalNumberOfElements=0;
379
380     //_numberOfGaussPoint = new int[numberOfElementTypesInFamily] ;
381
382     //int * numberIndex = new int[numberOfElementTypesInFamily+1];
383     //numberIndex[0]=1;
384     for (int i=0; i<numberOfElementTypesInFamily; i++) {
385       _geometricType[i]=tmp_Types[i] ;
386       //numberIndex[i+1]=numberIndex[i]+numberOfElementsInFamily[i];
387       _numberOfElements[i]=numberOfElementsInFamily[i]; // plutot un resize !!
388       _totalNumberOfElements+=_numberOfElements[i];
389       //_numberOfGaussPoint[i]=1;
390     }
391     //    delete[] numberOfElementsInFamily;
392     //    delete[] tmp_Types;
393     //    delete[] GeometricTypeNumber;
394       
395     // family on all ELEMENT ?
396     if (_totalNumberOfElements == 
397         _mesh->getNumberOfElementsWithPoly(Entity,MED_ALL_ELEMENTS)/* && Entity==MED_EN::MED_CELL*/) {
398       _isOnAllElts = true ;
399       // all others attributs are rights !
400       for (int i=0; i<_numberOfGeometricType; i++)
401         delete[] tmp_ElementsLists[i];
402     } else {
403       int *NumberValue = new int[_totalNumberOfElements];
404       int *NumberIndex = new int[_numberOfGeometricType+1];
405       NumberIndex[0]=1;
406       for (int i=0; i<_numberOfGeometricType; i++) {
407         NumberIndex[i+1]=NumberIndex[i]+_numberOfElements[i];
408         for (int j=NumberIndex[i]; j<NumberIndex[i+1]; j++)
409           NumberValue[j-1]=tmp_ElementsLists[i][j-NumberIndex[i]];
410         delete[] tmp_ElementsLists[i];
411       }
412       if(_number!=NULL) delete _number ;
413       _number = new MEDSKYLINEARRAY(_numberOfGeometricType,_totalNumberOfElements,NumberIndex,NumberValue);
414       delete[] NumberIndex ;
415       delete[] NumberValue ;
416     }
417   }
418   delete[] tmp_Types;
419   delete[] types;
420   delete[] numberOfElementsInFamily;
421
422   delete[] tmp_ElementsLists;
423
424   return Find ;
425 }
426