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