Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/med.git] / src / MEDMEM / MEDMEM_Field.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 #include "MEDMEM_Field.hxx"
23 #include "MEDMEM_Mesh.hxx"
24
25 using namespace std;
26 using namespace MEDMEM;
27 using namespace MED_EN;
28
29 // ---------------------------------
30 // FIELD_ : Constructors
31 // ---------------------------------
32 FIELD_::FIELD_(): 
33   _isRead(false),
34   _isMinMax(false),
35   _name(""), _description(""), _support((SUPPORT *)NULL),
36   _numberOfComponents(0), _numberOfValues(0),
37   //_componentsTypes((int *)NULL),
38   //_componentsNames((string *)NULL), 
39   //_componentsDescriptions((string *)NULL),
40   //_componentsUnits((UNIT*)NULL),
41   //_MEDComponentsUnits((string *)NULL),
42   _iterationNumber(-1),_time(0.0),_orderNumber(-1),
43   _valueType(MED_EN::MED_UNDEFINED_TYPE),
44   _interlacingType(MED_EN::MED_UNDEFINED_INTERLACE)
45 {
46   MESSAGE_MED("Constructeur FIELD_ sans parametre");
47 }
48
49 FIELD_::FIELD_(const SUPPORT * Support, const int NumberOfComponents):
50   _isRead(false),
51   _isMinMax(false),
52   _name(""), _description(""), _support(Support),
53   _numberOfComponents(NumberOfComponents),
54   _iterationNumber(-1),_time(0.0),_orderNumber(-1),
55   _valueType(MED_EN::MED_UNDEFINED_TYPE),
56   _interlacingType(MED_EN::MED_UNDEFINED_INTERLACE)
57 {
58   MESSAGE_MED("FIELD_(const SUPPORT * Support, const int NumberOfComponents)");
59
60   _numberOfValues = Support->getNumberOfElements(MED_ALL_ELEMENTS);
61   //_componentsTypes = new int[NumberOfComponents] ;
62   //_componentsNames = new string[NumberOfComponents];
63   //_componentsDescriptions = new string[NumberOfComponents];
64   //_componentsUnits = new UNIT[NumberOfComponents];
65   //_MEDComponentsUnits = new string[NumberOfComponents];
66   _componentsTypes.resize(NumberOfComponents);
67   _componentsNames.resize(NumberOfComponents);
68   _componentsDescriptions.resize(NumberOfComponents);
69   _componentsUnits.resize(NumberOfComponents);
70   _MEDComponentsUnits.resize(NumberOfComponents);
71   for(int i=0;i<NumberOfComponents;i++) {
72     _componentsTypes[i] = 0 ;
73   }
74   if(_support)
75     _support->addReference();
76 }
77
78 FIELD_& FIELD_::operator=(const FIELD_ &m) {
79
80   if ( this == &m) return *this;
81
82   _isRead             = m._isRead ;
83   _isMinMax           = m._isMinMax ;
84   _name               = m._name;
85   _description        = m._description;
86   _support            = m._support;   //Cf Opérateur de recopie du Support?
87   _numberOfComponents = m._numberOfComponents;
88   _numberOfValues     = m._numberOfValues;
89
90   //if (m._componentsTypes != NULL) {
91   //  _componentsTypes = new int[m._numberOfComponents] ;
92   //  memcpy(_componentsTypes,m._componentsTypes,sizeof(int)*m._numberOfComponents);
93   //} else 
94   //  _componentsTypes = (int *) NULL;
95
96   _componentsTypes.resize(_numberOfComponents);
97   for (int i=0; i<m._numberOfComponents; i++)
98     {_componentsTypes[i]=m._componentsTypes[i];}
99
100   _componentsNames.resize(_numberOfComponents);
101   _componentsDescriptions.resize(_numberOfComponents);
102   _componentsUnits.resize(_numberOfComponents);
103   _MEDComponentsUnits.resize(_numberOfComponents);
104
105   //_componentsNames = new string[m._numberOfComponents];
106   for (int i=0; i<m._numberOfComponents; i++)
107     {_componentsNames[i]=m._componentsNames[i];}
108   //_componentsDescriptions = new string[m._numberOfComponents];
109   for (int i=0; i<m._numberOfComponents; i++)
110     {_componentsDescriptions[i]=m._componentsDescriptions[i];}
111   //_componentsUnits = new UNIT[m._numberOfComponents];
112   for (int i=0; i<m._numberOfComponents; i++)
113     {_componentsUnits[i] = m._componentsUnits[i];}
114   // L'operateur '=' est defini dans la classe UNIT
115   //_MEDComponentsUnits = new string[m._numberOfComponents];
116   for (int i=0; i<m._numberOfComponents; i++)
117     {_MEDComponentsUnits[i] = m._MEDComponentsUnits[i];}
118
119   _iterationNumber = m._iterationNumber;
120   _time            = m._time;
121   _orderNumber     = m._orderNumber;
122
123   // _valueType et _interlacingType doivent uniquement être recopiés 
124   // par l'opérateur de recopie de FIELD<T,...>
125
126   //_drivers = m._drivers ; // PG : Well, same driver, what about m destructor !
127
128   return *this;
129 }
130
131 FIELD_::FIELD_(const FIELD_ &m)
132 {
133   _isRead = m._isRead ;
134   _isMinMax = m._isMinMax ;
135   _name = m._name;
136   _description = m._description;
137   _support = m._support;
138   if(_support)
139     _support->addReference();
140   _numberOfComponents = m._numberOfComponents;
141   _numberOfValues = m._numberOfValues;
142   copyGlobalInfo(m);
143   //_valueType = m._valueType;
144   // _valueType et _interlacingType doivent uniquement être recopiés 
145   // par l'opérateur de recopie de FIELD<T,...>
146   //_drivers = m._drivers ; // PG : Well, same driver, what about m destructor !
147 }
148
149 FIELD_::~FIELD_()
150 {
151   MESSAGE_MED("~FIELD_()");
152   //if ( _componentsTypes !=NULL)
153   //  delete[] _componentsTypes ;
154   //if ( _componentsNames !=NULL)
155   //  delete[] _componentsNames ;
156   //if ( _componentsDescriptions !=NULL)
157   //  delete[] _componentsDescriptions ;
158   //if ( _componentsUnits !=NULL)
159   //  delete[] _componentsUnits ;
160   //if ( _MEDComponentsUnits !=NULL)
161   //  delete[] _MEDComponentsUnits ;
162   // delete driver
163 //   vector<GENDRIVER *>::const_iterator it ;
164 //   SCRUTE_MED(_drivers.size());
165 //   int i=0;
166 //   for (it=_drivers.begin();it!=_drivers.end();it++) {
167 //     i++;
168 //     SCRUTE_MED(i);
169 //     delete (*it) ;
170
171
172   MESSAGE_MED("In this object FIELD_ there is(are) " << _drivers.size() << " driver(s)");
173
174   for (unsigned int index=0; index < _drivers.size(); index++ )
175     {
176       SCRUTE_MED(_drivers[index]);
177       if ( _drivers[index] != NULL) delete _drivers[index];
178     }
179   //CCAR: if _support is a SUPPORTClient remove reference
180   // This is correct but it's highlighting other problem
181  // if(_support)
182  //   _support->removeReference();
183 }
184
185 /*! 
186   \if developper
187   PROVISOIRE : retourne des volumes, surfaces ou longueurs suivant les cas
188   \endif
189 */
190 FIELD<double>* FIELD_::_getFieldSize() const
191 {
192     FIELD<double>* p_field_size;
193     switch (getSupport()->getEntity())
194     {
195         case MED_CELL :
196             switch (getSupport()->getMesh()->getMeshDimension() ) 
197             {
198                 case 1:
199                     p_field_size=getSupport()->getMesh()->getLength(getSupport() );
200                     break;
201                 case 2:
202                     p_field_size=getSupport()->getMesh()->getArea(getSupport() );
203                     break;
204                 case 3:
205                     p_field_size=getSupport()->getMesh()->getVolume(getSupport() );
206                     break;
207             }
208             break;
209             
210         case MED_FACE :
211             p_field_size=getSupport()->getMesh()->getArea(getSupport() );
212             break;
213
214         case MED_EDGE :
215             p_field_size=getSupport()->getMesh()->getLength(getSupport() );
216             break;
217     }
218     return p_field_size;
219 }
220
221
222 /*! 
223   \if developper
224   Check up the compatibility of field before computing sobolev norm 
225   \endif
226 */
227 void FIELD_::_checkNormCompatibility(const FIELD<double>* support_volume) const throw (MEDEXCEPTION)
228 {
229     string diagnosis;
230
231     if( getSupport()->getEntity() == MED_NODE )
232     {
233         diagnosis="Cannot compute sobolev norm on a field "+getName()+
234             " : it has support on nodes!";
235         throw MEDEXCEPTION(diagnosis.c_str());
236     }
237         
238     if (getNumberOfValues()*getNumberOfComponents()<= 0) // Size of array has to be strictly positive
239     {
240         diagnosis="Cannot compute the norm of "+getName()+
241             " : it size is non positive!";
242         throw MEDEXCEPTION(diagnosis.c_str());
243     }
244
245     if( getSupport()->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) != getNumberOfValues() ) {
246       diagnosis="Cannot compute Lnorm of "+getName()+
247         " : the suppors size not corresponded to number of elements!";
248       throw MEDEXCEPTION(diagnosis.c_str());
249     }
250
251     if (getGaussPresence() ) {
252       diagnosis="Cannot compute Lnorm of "+getName()+
253         " : Gauss numbers greater than one are not yet implemented!";
254       throw MEDEXCEPTION(diagnosis.c_str());
255     }
256
257     if(support_volume) // if the user has supplied the volume
258     {
259         if(support_volume->getSupport()!=getSupport())
260         {
261             diagnosis="Cannot compute Lnorm of "+getName()+
262             " : the volume furnished has not the same support!";
263             throw MEDEXCEPTION(diagnosis.c_str());
264         }
265         if(support_volume->getNumberOfValues()!=getNumberOfValues())
266         {
267             diagnosis="Cannot compute Lnorm of "+getName()+
268             " : the volume furnished has not the same number of values!";
269             throw MEDEXCEPTION(diagnosis.c_str());
270         }
271         if( getSupport()->getNumberOfElements() != 
272             support_volume->getSupport()->getNumberOfElements() ) {
273           diagnosis="Cannot compute Lnorm of "+getName()+
274             " : the supports have not the same number of elements!";
275           throw MEDEXCEPTION(diagnosis.c_str());
276         }
277     }
278
279 }
280
281 /*! 
282   \if developper
283    Check up the compatibility of fields before performing an arithmetic operation
284   \endif
285 */
286 void FIELD_::_checkFieldCompatibility(const FIELD_& m, const FIELD_& n, bool checkUnit) throw (MEDEXCEPTION)
287 {
288     string diagnosis;
289
290     // check-up, fill diagnosis if some incompatibility is found.
291
292     // Ne pas vérifier l'entrelacement
293     // Le compilo s'en occupe Rmq from EF
294
295     if(m._support != n._support)
296       {
297         if(!(*m._support==*n._support))
298           diagnosis+="They don't have the same support!";
299       }
300     else if(m._numberOfComponents != n._numberOfComponents)
301       diagnosis+="They don't have the same number of components!";
302     else if (m._valueType != n._valueType)
303       diagnosis+="They don't have the same type!";
304     else if(m._numberOfValues != n._numberOfValues)
305       diagnosis+="They don't have the same number of values!";
306     else
307       {
308         if(checkUnit)
309           {
310             for(int i=0; i<m._numberOfComponents; i++)
311               {
312                 // Not yet implemented   
313                 //          if(m._componentsTypes[i] != n._componentsTypes[i])
314                 //          {
315                 //              diagnosis+="Components don't have the same types!";
316                 //              break;
317                 //          }
318                 if(m._MEDComponentsUnits[i] != n._MEDComponentsUnits[i])
319                   {
320                     diagnosis+="Components don't have the same units!";
321                     break;
322                   }
323               }
324           }
325       }
326
327     if(diagnosis.size()) // if fields are not compatible : complete diagnosis and throw exception
328     {
329         diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
330                  + n._name + " are not compatible.\n" + diagnosis;
331         throw MEDEXCEPTION(diagnosis.c_str());
332     }
333
334     if( m.getNumberOfValues()<=0 || m.getNumberOfComponents()<=0) // check up the size is strictly positive
335     {
336         diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
337                  + n._name + " are empty! (size<=0).\n";
338         throw MEDEXCEPTION(diagnosis.c_str());
339     }
340
341 }
342
343 void FIELD_::_deepCheckFieldCompatibility(const FIELD_& m, const FIELD_& n , bool checkUnit ) throw (MEDEXCEPTION)
344 {
345   string diagnosis;
346
347   // check-up, fill diagnosis if some incompatibility is found.
348
349   // Ne pas vérifier l'entrelacement
350   // Le compilo s'en occupe Rmq from EF
351
352     if(m._support != n._support)
353       {
354         if(!(m._support->deepCompare(*n._support)))
355           diagnosis+="They don't have the same support!";
356       }
357     else if (m._valueType != n._valueType)
358       diagnosis+="They don't have the same type!";
359     else if(m._numberOfComponents != n._numberOfComponents)
360       diagnosis+="They don't have the same number of components!";
361     else if(m._numberOfValues != n._numberOfValues)
362       diagnosis+="They don't have the same number of values!";
363     else
364       {
365         if(checkUnit)
366           {
367             for(int i=0; i<m._numberOfComponents; i++)
368               {
369                 if(m._MEDComponentsUnits[i] != n._MEDComponentsUnits[i])
370                   {
371                     diagnosis+="Components don't have the same units!";
372                     break;
373                   }
374               }
375           }
376       }
377
378     if(diagnosis.size()) // if fields are not compatible : complete diagnosis and throw exception
379     {
380         diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
381                  + n._name + " are not compatible.\n" + diagnosis;
382         throw MEDEXCEPTION(diagnosis.c_str());
383     }
384
385     if( m.getNumberOfValues()<=0 || m.getNumberOfComponents()<=0) // check up the size is strictly positive
386     {
387         diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
388                  + n._name + " are empty! (size<=0).\n";
389         throw MEDEXCEPTION(diagnosis.c_str());
390     }
391
392
393
394 void     FIELD_::rmDriver      (int index)
395 {
396   MESSAGE_MED("void FIELD_::rmDriver(int index) : removing the driver " << index);
397 }
398
399 int      FIELD_::addDriver     (driverTypes driverType, 
400                                 const string & fileName,
401                                 const string & driverFieldName,
402                                 MED_EN::med_mode_acces access)
403 {
404   MESSAGE_MED("int FIELD_::addDriver(driverTypes driverType, const string & fileName, const string & driverFieldName) : adding the driver " << driverType << " fileName = " << fileName.c_str() << " driverFieldName = " << driverFieldName.c_str());
405   return 0;
406 }
407
408 int      FIELD_::addDriver     (GENDRIVER & driver)
409 {
410   MESSAGE_MED("int FIELD_::addDriver(GENDRIVER & driver) : driver " << driver);
411   return 0;
412 }
413
414 void     FIELD_::openAppend    ( void )                               {}
415 void     FIELD_::write         (const GENDRIVER &)                    {}
416 void     FIELD_::writeAppend   (const GENDRIVER &)                    {}
417 void     FIELD_::read          (const GENDRIVER &)                    {}
418 void     FIELD_::write         (int , const string & ) {}
419 void     FIELD_::writeAppend   (int , const string & ) {}
420 void     FIELD_::read          (int )                                  {}
421 void     FIELD_::copyGlobalInfo(const FIELD_& m)
422 {  
423
424   _componentsTypes.resize(_numberOfComponents);
425   _componentsNames.resize(_numberOfComponents);
426   _componentsDescriptions.resize(_numberOfComponents);
427   _componentsUnits.resize(_numberOfComponents);
428   _MEDComponentsUnits.resize(_numberOfComponents);
429
430   for (int i=0; i<m._numberOfComponents; i++)
431     {_componentsTypes[i]=m._componentsTypes[i];}
432
433   //if (m._componentsTypes != NULL)
434   //  {
435   //    _componentsTypes = new int[m._numberOfComponents] ;
436   //    memcpy(_componentsTypes,m._componentsTypes,sizeof(int)*m._numberOfComponents);
437   //  }
438   //else
439   //  _componentsTypes = (int *) NULL;
440
441   //_componentsNames = new string[m._numberOfComponents];
442   for (int i=0; i<m._numberOfComponents; i++)
443     _componentsNames[i]=m._componentsNames[i];
444   //_componentsDescriptions = new string[m._numberOfComponents];
445   for (int i=0; i<m._numberOfComponents; i++)
446     _componentsDescriptions[i]=m._componentsDescriptions[i];
447
448   //if (m._componentsUnits != NULL)
449   //  {
450   //    _componentsUnits = new UNIT[m._numberOfComponents];
451   for (int i=0; i<m._numberOfComponents; i++)
452     _componentsUnits[i] = m._componentsUnits[i];
453   //  }
454   //else
455   //  _componentsUnits=(UNIT*)NULL;
456   
457   // L'operateur '=' est defini dans la classe UNIT
458   //_MEDComponentsUnits = new string[m._numberOfComponents];
459   for (int i=0; i<m._numberOfComponents; i++)
460     {_MEDComponentsUnits[i] = m._MEDComponentsUnits[i];}
461
462   _iterationNumber = m._iterationNumber;
463   _time = m._time;
464   _orderNumber = m._orderNumber;
465 }