1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "MEDMEM_Field.hxx"
24 #include "MEDMEM_Mesh.hxx"
27 using namespace MEDMEM;
28 using namespace MED_EN;
30 // ---------------------------------
31 // FIELD_ : Constructors
32 // ---------------------------------
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)
42 MESSAGE_MED("Constructeur FIELD_ sans parametre");
45 FIELD_::FIELD_(const SUPPORT * Support, const int NumberOfComponents):
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)
54 MESSAGE_MED("FIELD_(const SUPPORT * Support, const int NumberOfComponents)");
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 ;
66 _support->addReference();
69 FIELD_& FIELD_::operator=(const FIELD_ &m) {
71 if ( this == &m) return *this;
74 _isMinMax = m._isMinMax ;
76 _description = m._description;
77 if(_support!=m._support)
80 _support->removeReference();
81 _support=m._support; //Cf Opérateur de recopie du Support?
83 _support->addReference();
85 _numberOfComponents = m._numberOfComponents;
86 _numberOfValues = m._numberOfValues;
88 _componentsTypes.resize(_numberOfComponents);
89 for (int i=0; i<m._numberOfComponents; i++)
90 {_componentsTypes[i]=m._componentsTypes[i];}
92 _componentsNames.resize(_numberOfComponents);
93 _componentsDescriptions.resize(_numberOfComponents);
94 _componentsUnits.resize(_numberOfComponents);
95 _MEDComponentsUnits.resize(_numberOfComponents);
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];}
107 _iterationNumber = m._iterationNumber;
109 _orderNumber = m._orderNumber;
111 // _valueType et _interlacingType doivent uniquement être recopiés
112 // par l'opérateur de recopie de FIELD<T,...>
114 //_drivers = m._drivers ; // PG : Well, same driver, what about m destructor !
119 FIELD_::FIELD_(const FIELD_ &m)
121 _isRead = m._isRead ;
122 _isMinMax = m._isMinMax ;
124 _description = m._description;
125 _support = m._support;
127 _support->addReference();
128 _numberOfComponents = m._numberOfComponents;
129 _numberOfValues = m._numberOfValues;
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 !
139 MESSAGE_MED("~FIELD_()");
141 MESSAGE_MED("In this object FIELD_ there is(are) " << _drivers.size() << " driver(s)");
143 for (unsigned int index=0; index < _drivers.size(); index++ )
145 SCRUTE_MED(_drivers[index]);
146 if ( _drivers[index] != NULL) delete _drivers[index];
150 _support->removeReference();
156 PROVISOIRE : retourne des volumes, surfaces ou longueurs suivant les cas
159 FIELD<double>* FIELD_::_getFieldSize(const SUPPORT *subSupport) const
161 FIELD<double>* p_field_size;
163 const SUPPORT* support = subSupport;
166 if ( getSupport()->getEntity() == MED_NODE )
167 support = getSupport()->getMesh()->getSupportOnAll( MED_CELL );
169 support = getSupport();
170 support->addReference();
172 const GMESH* mesh = getSupport()->getMesh();
173 switch (getSupport()->getEntity())
176 switch (mesh->getMeshDimension() )
179 p_field_size=mesh->getLength( support );
182 p_field_size=mesh->getArea( support );
185 p_field_size=mesh->getVolume( support );
191 p_field_size=mesh->getArea( support );
195 p_field_size=mesh->getLength( support );
197 case MED_NODE : // issue 0020120: [CEA 206] normL2 on NODE field
199 switch (mesh->getMeshDimension() )
202 p_field_size=mesh->getLength( support );
205 p_field_size=mesh->getArea( support );
208 p_field_size=mesh->getVolume( support );
214 if(!subSupport && support)
215 support->removeReference();
222 Check up the compatibility of field before computing sobolev norm
225 void FIELD_::_checkNormCompatibility(const FIELD<double>* support_volume,
226 const bool nodalAllowed) const throw (MEDEXCEPTION)
230 if( getSupport()->getEntity() == MED_NODE)
234 diagnosis="Cannot compute sobolev norm on a field "+getName()+
235 " : it has support on nodes!";
236 throw MEDEXCEPTION(diagnosis.c_str());
238 if ( !getSupport()->getMesh() )
240 diagnosis="Cannot compute Lnorm of nodal field "+getName()+
241 " : it's support has no mesh reference";
242 throw MEDEXCEPTION(diagnosis.c_str());
244 if ( !getSupport()->getMesh()->getIsAGrid() &&
245 !( (const MESH*)getSupport()->getMesh() )->existConnectivity(MED_NODAL,MED_CELL) )
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());
253 if (getNumberOfValues()*getNumberOfComponents()<= 0) // Size of array has to be strictly positive
255 diagnosis="Cannot compute the norm of "+getName()+
256 " : it size is non positive!";
257 throw MEDEXCEPTION(diagnosis.c_str());
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());
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());
272 if(support_volume) // if the user has supplied the volume
274 if ( getSupport()->getEntity() == MED_NODE )
276 if (support_volume->getNumberOfValues()!=
277 getSupport()->getMesh()->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS))
279 diagnosis="Cannot compute Lnorm of nodal field "+getName()+
280 " : the volume furnished has wrong number of values";
281 throw MEDEXCEPTION(diagnosis.c_str());
285 if(support_volume->getSupport()!=getSupport())
287 diagnosis="Cannot compute Lnorm of "+getName()+
288 " : the volume furnished has not the same support!";
289 throw MEDEXCEPTION(diagnosis.c_str());
291 if(support_volume->getNumberOfValues()!=getNumberOfValues())
293 diagnosis="Cannot compute Lnorm of "+getName()+
294 " : the volume furnished has not the same number of values!";
295 throw MEDEXCEPTION(diagnosis.c_str());
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());
309 Check up the compatibility of fields before performing an arithmetic operation
312 void FIELD_::_checkFieldCompatibility(const FIELD_& m, const FIELD_& n, bool checkUnit) throw (MEDEXCEPTION)
316 // check-up, fill diagnosis if some incompatibility is found.
318 // Ne pas vérifier l'entrelacement
319 // Le compilo s'en occupe Rmq from EF
321 if(m._support != n._support)
323 if(!(*m._support==*n._support))
324 diagnosis+="They don't have the same support!";
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!";
336 for(int i=0; i<m._numberOfComponents; i++)
338 // Not yet implemented
339 // if(m._componentsTypes[i] != n._componentsTypes[i])
341 // diagnosis+="Components don't have the same types!";
344 if(m._MEDComponentsUnits[i] != n._MEDComponentsUnits[i])
346 diagnosis+="Components don't have the same units!";
353 if(diagnosis.size()) // if fields are not compatible : complete diagnosis and throw exception
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());
360 if( m.getNumberOfValues()<=0 || m.getNumberOfComponents()<=0) // check up the size is strictly positive
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());
369 void FIELD_::_deepCheckFieldCompatibility(const FIELD_& m, const FIELD_& n , bool checkUnit ) throw (MEDEXCEPTION)
373 // check-up, fill diagnosis if some incompatibility is found.
375 // Ne pas vérifier l'entrelacement
376 // Le compilo s'en occupe Rmq from EF
378 if(m._support != n._support)
380 if(!(m._support->deepCompare(*n._support)))
381 diagnosis+="They don't have the same support!";
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!";
393 for(int i=0; i<m._numberOfComponents; i++)
395 if(m._MEDComponentsUnits[i] != n._MEDComponentsUnits[i])
397 diagnosis+="Components don't have the same units!";
404 if(diagnosis.size()) // if fields are not compatible : complete diagnosis and throw exception
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());
411 if( m.getNumberOfValues()<=0 || m.getNumberOfComponents()<=0) // check up the size is strictly positive
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());
420 void FIELD_::rmDriver (int index)
422 MESSAGE_MED("void FIELD_::rmDriver(int index) : removing the driver " << index);
425 int FIELD_::addDriver (driverTypes driverType,
426 const string & fileName,
427 const string & driverFieldName,
428 MED_EN::med_mode_acces access)
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());
434 int FIELD_::addDriver (GENDRIVER & driver)
436 MESSAGE_MED("int FIELD_::addDriver(GENDRIVER & driver) : driver " << driver);
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)
455 _componentsTypes.resize(_numberOfComponents);
456 _componentsNames.resize(_numberOfComponents);
457 _componentsDescriptions.resize(_numberOfComponents);
458 _componentsUnits.resize(_numberOfComponents);
459 _MEDComponentsUnits.resize(_numberOfComponents);
461 for (int i=0; i<m._numberOfComponents; i++)
462 {_componentsTypes[i]=m._componentsTypes[i];}
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];
469 for (int i=0; i<m._numberOfComponents; i++)
470 _componentsUnits[i] = m._componentsUnits[i];
472 // L'operateur '=' est defini dans la classe UNIT
473 for (int i=0; i<m._numberOfComponents; i++)
474 {_MEDComponentsUnits[i] = m._MEDComponentsUnits[i];}
476 _iterationNumber = m._iterationNumber;
478 _orderNumber = m._orderNumber;