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