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