1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
18 // See http://www.salome-platform.org/
33 #include "MEDMEM_Utilities.hxx"
34 #include "MEDMEM_Exception.hxx"
35 #include "MEDMEM_define.hxx"
36 #include "MEDMEM_Support.hxx"
37 #include "MEDMEM_Unit.hxx"
38 #include "MEDMEM_nArray.hxx"
39 #include "MEDMEM_GenDriver.hxx"
40 #include "MEDMEM_ArrayInterface.hxx"
41 #include "MEDMEM_FieldForward.hxx"
45 This class contains all the informations related with a template class FIELD :
46 - Components descriptions
47 - Time step description
48 - Location of the values (a SUPPORT class)
54 template < typename T > struct SET_VALUE_TYPE {
55 static const MED_EN::med_type_champ _valueType = MED_EN::MED_UNDEFINED_TYPE;};
56 template < > struct SET_VALUE_TYPE<double> {
57 static const MED_EN::med_type_champ _valueType = MED_EN::MED_REEL64; };
58 template < > struct SET_VALUE_TYPE<int> {
59 static const MED_EN::med_type_champ _valueType = MED_EN::MED_INT32; };
61 template < typename T > struct SET_INTERLACING_TYPE {
62 static const MED_EN::medModeSwitch _interlacingType = MED_EN::MED_UNDEFINED_INTERLACE; };
63 template < > struct SET_INTERLACING_TYPE<FullInterlace>{
64 static const MED_EN::medModeSwitch _interlacingType = MED_EN::MED_FULL_INTERLACE; };
65 template < > struct SET_INTERLACING_TYPE<NoInterlace> {
66 static const MED_EN::medModeSwitch _interlacingType = MED_EN::MED_NO_INTERLACE; };
68 class FIELD_ // GENERIC POINTER TO a template <class T, class INTERLACING_TAG> class FIELD
69 { // ùpihjpmoçhmpç_hmù
88 Pointer to the support the field deals with.
91 const SUPPORT * _support ;
95 Number of field's components.
98 int _numberOfComponents ;
101 Number of field's values.
104 int _numberOfValues ;
108 Array of size _numberOfComponents. \n
109 (constant, scalar, vector, tensor)\n
110 We could use an array of integer to store
111 numbers of values: \n
113 - space dimension for vector,\n
114 - space dimension square for tensor.\n
115 So numbers of values per entities would be
116 sum of _componentsTypes array.
118 Not implemented yet! All type are scalar !
121 int * _componentsTypes ;
124 Array of size _numberOfComponents
125 storing components names if any.
128 string * _componentsNames;
131 Array of size _numberOfComponents
132 storing components descriptions if any.
135 string * _componentsDescriptions;
138 Array of size _numberOfComponents
139 storing components units if any.
142 UNIT * _componentsUnits;
145 Array of size _numberOfComponents
146 storing components units if any.
149 string * _MEDComponentsUnits;
152 Iteration number of the field.
155 int _iterationNumber ;
164 Order number of the field.
170 At the initialization step of the field using the constructors; this attribute,
171 the value type (integer or real) , is set automatically. There is a get method
172 but not a set method for this attribute.
175 MED_EN::med_type_champ _valueType ;
178 At the initialization step of the field using the constructors; this attribute,
179 the interlacing type (full interlace or no interlace field value storage), is set
180 automatically. There is a get method but not a set method for this attribute.
183 MED_EN::medModeSwitch _interlacingType;
185 vector<GENDRIVER *> _drivers; // Storage of the drivers currently in use
186 static void _checkFieldCompatibility(const FIELD_& m, const FIELD_& n, bool checkUnit=true) throw (MEDEXCEPTION);
187 static void _deepCheckFieldCompatibility(const FIELD_& m, const FIELD_& n, bool checkUnit=true) throw (MEDEXCEPTION);
188 void _checkNormCompatibility(const FIELD<double>* p_field_volume=NULL) const throw (MEDEXCEPTION);
189 FIELD<double>* _getFieldSize() const;
193 friend class MED_MED_RDONLY_DRIVER21;
194 friend class MED_MED_WRONLY_DRIVER21;
195 friend class MED_MED_RDWR_DRIVER21;
196 friend class MED_MED_RDONLY_DRIVER22;
197 friend class MED_MED_WRONLY_DRIVER22;
198 friend class MED_MED_RDWR_DRIVER22;
200 friend class VTK_MED_DRIVER;
209 FIELD_(const SUPPORT * Support, const int NumberOfComponents);
213 FIELD_(const FIELD_ &m);
220 FIELD_& operator=(const FIELD_ &m);
222 virtual void rmDriver(int index=0);
223 virtual int addDriver(driverTypes driverType,
224 const string & fileName="Default File Name.med",
225 const string & driverFieldName="Default Field Nam",
226 MED_EN::med_mode_acces access=MED_EN::MED_REMP) ;
228 virtual int addDriver( GENDRIVER & driver);
229 virtual void read (const GENDRIVER &);
230 virtual void read(int index=0);
231 virtual void openAppend( void );
232 virtual void write(const GENDRIVER &);
233 virtual void write(int index=0, const string & driverName="");
235 virtual void writeAppend(const GENDRIVER &);
236 virtual void writeAppend(int index=0, const string & driverName="");
238 inline void setName(const string Name);
239 inline string getName() const;
240 inline void setDescription(const string Description);
241 inline string getDescription() const;
242 inline const SUPPORT * getSupport() const;
243 inline void setSupport(const SUPPORT * support);
244 inline void setNumberOfComponents(const int NumberOfComponents);
245 inline int getNumberOfComponents() const;
246 inline void setNumberOfValues(const int NumberOfValues);
247 inline int getNumberOfValues() const;
248 // inline void setComponentType(int *ComponentType);
249 // inline int * getComponentType() const;
250 // inline int getComponentTypeI(int i) const;
251 inline void setComponentsNames(const string * ComponentsNames);
252 inline void setComponentName(int i, const string ComponentName);
253 inline const string * getComponentsNames() const;
254 inline string getComponentName(int i) const;
255 inline void setComponentsDescriptions(const string * ComponentsDescriptions);
256 inline void setComponentDescription(int i, const string ComponentDescription);
257 inline const string * getComponentsDescriptions() const;
258 inline string getComponentDescription(int i) const;
260 // provisoire : en attendant de regler le probleme des unites !
261 inline void setComponentsUnits(const UNIT * ComponentsUnits);
262 inline const UNIT * getComponentsUnits() const;
263 inline const UNIT * getComponentUnit(int i) const;
264 inline void setMEDComponentsUnits(const string * MEDComponentsUnits);
265 inline void setMEDComponentUnit(int i, const string MEDComponentUnit);
266 inline const string * getMEDComponentsUnits() const;
267 inline string getMEDComponentUnit(int i) const;
269 inline void setIterationNumber(int IterationNumber);
270 inline int getIterationNumber() const;
271 inline void setTime(double Time);
272 inline double getTime() const;
273 inline void setOrderNumber(int OrderNumber);
274 inline int getOrderNumber() const;
276 inline MED_EN::med_type_champ getValueType () const;
277 inline MED_EN::medModeSwitch getInterlacingType() const;
278 virtual inline bool getGaussPresence() const throw (MEDEXCEPTION);
280 void copyGlobalInfo(const FIELD_& m);
283 // ---------------------------------
284 // Implemented Methods : constructor
285 // ---------------------------------
293 inline void FIELD_::setName(const string Name)
300 inline string FIELD_::getName() const
305 Set FIELD description.
307 inline void FIELD_::setDescription(const string Description)
309 _description=Description;
312 Get FIELD description.
314 inline string FIELD_::getDescription() const
319 Set FIELD number of components.
321 inline void FIELD_::setNumberOfComponents(const int NumberOfComponents)
323 _numberOfComponents=NumberOfComponents;
326 Get FIELD number of components.
328 inline int FIELD_::getNumberOfComponents() const
330 return _numberOfComponents ;
333 Set FIELD number of values.
335 It must be the same than in the associated SUPPORT object.
337 inline void FIELD_::setNumberOfValues(const int NumberOfValues)
339 _numberOfValues=NumberOfValues;
342 Get FIELD number of value.
344 inline int FIELD_::getNumberOfValues() const
346 return _numberOfValues ;
349 // inline void FIELD_::setComponentType(int *ComponentType)
351 // _componentsTypes=ComponentType ;
353 // inline int * FIELD_::getComponentType() const
355 // return _componentsTypes ;
357 // inline int FIELD_::getComponentTypeI(int i) const
359 // return _componentsTypes[i-1] ;
363 Set FIELD components names.
365 Duplicate the ComponentsNames string array to put components names in
366 FIELD. ComponentsNames size must be equal to number of components.
368 inline void FIELD_::setComponentsNames(const string * ComponentsNames)
370 if (NULL == _componentsNames)
371 _componentsNames = new string[_numberOfComponents] ;
372 for (int i=0; i<_numberOfComponents; i++)
373 _componentsNames[i]=ComponentsNames[i] ;
376 Set FIELD i^th component name.
378 i must be >=1 and <= number of components.
380 inline void FIELD_::setComponentName(int i, const string ComponentName)
382 _componentsNames[i-1]=ComponentName ;
385 Get a reference to the string array which contain the components names.
387 This Array size is equal to number of components
389 inline const string * FIELD_::getComponentsNames() const
391 return _componentsNames ;
394 Get the name of the i^th component.
396 inline string FIELD_::getComponentName(int i) const
398 return _componentsNames[i-1] ;
401 Set FIELD components descriptions.
403 Duplicate the ComponentsDescriptions string array to put components
404 descriptions in FIELD.
405 ComponentsDescriptions size must be equal to number of components.
407 inline void FIELD_::setComponentsDescriptions(const string * ComponentsDescriptions)
409 if (NULL == _componentsDescriptions)
410 _componentsDescriptions = new string[_numberOfComponents] ;
411 for (int i=0; i<_numberOfComponents; i++)
412 _componentsDescriptions[i]=ComponentsDescriptions[i] ;
415 Set FIELD i^th component description.
417 i must be >=1 and <= number of components.
419 inline void FIELD_::setComponentDescription(int i,const string ComponentDescription)
421 _componentsDescriptions[i-1]=ComponentDescription ;
424 Get a reference to the string array which contain the components descriptions.
426 This Array size is equal to number of components
428 inline const string * FIELD_::getComponentsDescriptions() const
430 return _componentsDescriptions ;
433 Get the description of the i^th component.
435 inline string FIELD_::getComponentDescription(int i) const
437 return _componentsDescriptions[i-1];
442 Set FIELD components UNIT.
444 Duplicate the ComponentsUnits UNIT array to put components
446 ComponentsUnits size must be equal to number of components.
448 inline void FIELD_::setComponentsUnits(const UNIT * ComponentsUnits)
450 if (NULL == _componentsUnits)
451 _componentsUnits = new UNIT[_numberOfComponents] ;
452 for (int i=0; i<_numberOfComponents; i++)
453 _componentsUnits[i]=ComponentsUnits[i] ;
456 Get a reference to the UNIT array which contain the components units.
458 This Array size is equal to number of components
460 inline const UNIT * FIELD_::getComponentsUnits() const
462 return _componentsUnits ;
465 Get the UNIT of the i^th component.
467 inline const UNIT * FIELD_::getComponentUnit(int i) const
469 return &_componentsUnits[i-1] ;
472 Set FIELD components unit.
474 Duplicate the MEDComponentsUnits string array to put components
476 MEDComponentsUnits size must be equal to number of components.
479 inline void FIELD_::setMEDComponentsUnits(const string * MEDComponentsUnits)
481 if (NULL == _MEDComponentsUnits)
482 _MEDComponentsUnits = new string[_numberOfComponents] ;
483 for (int i=0; i<_numberOfComponents; i++)
484 _MEDComponentsUnits[i]=MEDComponentsUnits[i] ;
487 Set FIELD i^th component unit.
489 i must be >=1 and <= number of components.
491 inline void FIELD_::setMEDComponentUnit(int i, const string MEDComponentUnit)
493 _MEDComponentsUnits[i-1]=MEDComponentUnit ;
496 Get a reference to the string array which contain the components units.
498 This Array size is equal to number of components
500 inline const string * FIELD_::getMEDComponentsUnits() const
502 return _MEDComponentsUnits ;
505 Get the string for unit of the i^th component.
507 inline string FIELD_::getMEDComponentUnit(int i) const
509 return _MEDComponentsUnits[i-1] ;
512 Set the iteration number where FIELD has been calculated.
514 inline void FIELD_::setIterationNumber(int IterationNumber)
516 _iterationNumber=IterationNumber;
519 Get the iteration number where FIELD has been calculated.
521 inline int FIELD_::getIterationNumber() const
523 return _iterationNumber ;
526 Set the time (in second) where FIELD has been calculated.
528 inline void FIELD_::setTime(double Time)
533 Get the time (in second) where FIELD has been calculated.
535 inline double FIELD_::getTime() const
540 Set the order number where FIELD has been calculated.
542 It corresponds to internal iteration during one time step.
544 inline void FIELD_::setOrderNumber(int OrderNumber)
546 _orderNumber=OrderNumber ;
549 Get the order number where FIELD has been calculated.
551 inline int FIELD_::getOrderNumber() const
553 return _orderNumber ;
556 Get a reference to the SUPPORT object associated to FIELD.
558 inline const SUPPORT * FIELD_::getSupport() const
563 Set the reference to the SUPPORT object associated to FIELD.
565 Reference is not duplicate, so it must not be deleted.
567 inline void FIELD_::setSupport(const SUPPORT * support)
569 //A.G. Addings for RC
571 _support->removeReference();
574 _support->addReference();
577 Get the FIELD med value type (MED_INT32 or MED_REEL64).
579 inline MED_EN::med_type_champ FIELD_::getValueType () const
585 Get the FIELD med interlacing type (MED_FULL_INTERLACE or MED_NO_INTERLACE).
587 inline MED_EN::medModeSwitch FIELD_::getInterlacingType () const
589 return _interlacingType ;
593 Get the FIELD gauss presence.
595 inline bool FIELD_::getGaussPresence() const throw (MEDEXCEPTION)
597 const char * LOC = "FIELD_::getGaussPresence() : ";
598 throw MEDEXCEPTION(STRING(LOC) << " This FIELD_ doesn't rely on a FIELD<T>" );
601 } //End namespace MEDMEM
603 /////////////////////////
604 // END OF CLASS FIELD_ //
605 /////////////////////////
609 This template class contains informations related with a FIELD :
610 - Values of the field, their type (real or integer), the storage mode (full interlace or
617 template<class T2> class MED_FIELD_RDONLY_DRIVER21;
618 template<class T2> class MED_FIELD_WRONLY_DRIVER21;
619 template<class T2> class MED_FIELD_RDONLY_DRIVER22;
620 template<class T2> class MED_FIELD_WRONLY_DRIVER22;
621 template<class T2> class VTK_FIELD_DRIVER;
624 class INTERLACING_TAG
625 > class FIELD : public FIELD_
629 typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,NoGauss>::Array ArrayNoGauss;
630 typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,Gauss>::Array ArrayGauss;
631 typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo;
632 typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
633 typedef MEDMEM_Array_ Array;
635 // array of value of type T
638 static T _scalarForPow;
642 void _operation(const FIELD& m,const FIELD& n, char* Op);
643 void _operationInitialize(const FIELD& m,const FIELD& n, char* Op);
644 void _add_in_place(const FIELD& m,const FIELD& n);
645 void _sub_in_place(const FIELD& m,const FIELD& n);
646 void _mul_in_place(const FIELD& m,const FIELD& n);
647 void _div_in_place(const FIELD& m,const FIELD& n) throw (MEDEXCEPTION);
652 FIELD(const FIELD &m);
653 FIELD(const SUPPORT * Support, const int NumberOfComponents) throw (MEDEXCEPTION) ;
654 FIELD( driverTypes driverType,
655 const string & fileName, const string & fieldDriverName,
656 const int iterationNumber=-1, const int orderNumber=-1)
657 throw (MEDEXCEPTION);
658 FIELD(const SUPPORT * Support, driverTypes driverType,
659 const string & fileName="", const string & fieldName="",
660 const int iterationNumber = -1, const int orderNumber = -1)
661 throw (MEDEXCEPTION);
664 FIELD & operator=(const FIELD &m);
666 const FIELD operator+(const FIELD& m) const;
667 const FIELD operator-(const FIELD& m) const;
668 const FIELD operator*(const FIELD& m) const;
669 const FIELD operator/(const FIELD& m) const;
670 const FIELD operator-() const;
671 FIELD& operator+=(const FIELD& m);
672 FIELD& operator-=(const FIELD& m);
673 FIELD& operator*=(const FIELD& m);
674 FIELD& operator/=(const FIELD& m);
675 static FIELD* add(const FIELD& m, const FIELD& n);
676 static FIELD* addDeep(const FIELD& m, const FIELD& n);
677 static FIELD* sub(const FIELD& m, const FIELD& n);
678 static FIELD* subDeep(const FIELD& m, const FIELD& n);
679 static FIELD* mul(const FIELD& m, const FIELD& n);
680 static FIELD* mulDeep(const FIELD& m, const FIELD& n);
681 static FIELD* div(const FIELD& m, const FIELD& n);
682 static FIELD* divDeep(const FIELD& m, const FIELD& n);
683 double normMax() const throw (MEDEXCEPTION);
684 double norm2() const throw (MEDEXCEPTION);
685 void applyLin(T a, T b);
686 template <T T_function(T)> void applyFunc();
687 void applyPow(T scalar);
688 static FIELD* scalarProduct(const FIELD& m, const FIELD& n, bool deepCheck=false);
689 double normL2(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
690 double normL2(const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
691 double normL1(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
692 double normL1(const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
693 FIELD* extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION);
695 friend class MED_FIELD_RDONLY_DRIVER21<T>;
696 friend class MED_FIELD_WRONLY_DRIVER21<T>;
697 friend class MED_FIELD_RDONLY_DRIVER22<T>;
698 friend class MED_FIELD_WRONLY_DRIVER22<T>;
699 friend class VTK_FIELD_DRIVER<T>;
700 //friend class MED_FIELD_RDWR_DRIVER <T>;
703 void rmDriver(int index=0);
704 int addDriver(driverTypes driverType,
705 const string & fileName="Default File Name.med",
706 const string & driverFieldName="Default Field Name",
707 MED_EN::med_mode_acces access=MED_EN::MED_REMP) ;
709 int addDriver(GENDRIVER & driver);
711 void allocValue(const int NumberOfComponents);
712 void allocValue(const int NumberOfComponents, const int LengthValue);
716 inline void read(int index=0);
717 inline void read(const GENDRIVER & genDriver);
718 inline void write(int index=0, const string & driverName = "");
719 inline void write(const GENDRIVER &);
721 inline void writeAppend(int index=0, const string & driverName = "");
722 inline void writeAppend(const GENDRIVER &);
724 inline MEDMEM_Array_ * getArray() const throw (MEDEXCEPTION);
725 inline ArrayGauss * getArrayGauss() const throw (MEDEXCEPTION);
726 inline ArrayNoGauss * getArrayNoGauss() const throw (MEDEXCEPTION);
727 inline bool getGaussPresence() const throw (MEDEXCEPTION);
729 inline int getValueLength() const throw (MEDEXCEPTION);
730 inline const T* getValue() const throw (MEDEXCEPTION);
731 inline const T* getRow(int i) const throw (MEDEXCEPTION);
732 inline const T* getColumn(int j) const throw (MEDEXCEPTION);
733 inline T getValueIJ(int i,int j) const throw (MEDEXCEPTION);
734 bool getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION);
736 inline void setArray(MEDMEM_Array_ *value) throw (MEDEXCEPTION);
737 inline void setValue( T* value) throw (MEDEXCEPTION);
738 inline void setRow( int i, T* value) throw (MEDEXCEPTION);
739 inline void setColumn( int i, T* value) throw (MEDEXCEPTION);
740 inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION);
743 This fonction feeds the FIELD<double> private attributs _value with the
744 volume of each cells belonging to the argument Support. The field has to be
745 initialised via the constructor FIELD<double>(const SUPPORT * , const int )
746 with Support as SUPPORT argument, 1 has the number of components, and Support
747 has be a SUPPORT on 3D cells. This initialisation could be done by the empty
748 constructor followed by a setSupport and setNumberOfComponents call.
750 void getVolume() const throw (MEDEXCEPTION) ;
752 This fonction feeds the FIELD<double> private attributs _value with the
753 area of each cells (or faces) belonging to the attribut _support. The field
754 has to be initialised via the constructor FIELD<double>(const SUPPORT * ,
755 const int ) with 1 has the number of components, and _support has be a
756 SUPPORT on 2D cells or 3D faces. This initialisation could be done by the
757 empty constructor followed by a setSupport and setNumberOfComponents call.
759 void getArea() const throw (MEDEXCEPTION) ;
761 This fonction feeds the FIELD<double> private attributs _value with the
762 length of each segments belonging to the attribut _support. The field has
763 to be initialised via the constructor FIELD<double>(const SUPPORT * ,
764 const int ) with 1 has the number of components, and _support has be a
765 SUPPORT on 3D edges or 2D faces. This initialisation could be done by the
766 empty constructor followed by a setSupport and setNumberOfComponents call.
768 void getLength() const throw (MEDEXCEPTION) ;
770 This fonction feeds the FIELD<double> private attributs _value with the
771 normal vector of each faces belonging to the attribut _support. The field
772 has to be initialised via the constructor FIELD<double>(const SUPPORT * ,
773 const int ) with the space dimension has the number of components, and
774 _support has be a SUPPORT on 3D or 2D faces. This initialisation could be done
775 by the empty constructor followed by a setSupport and setNumberOfComponents
778 void getNormal() const throw (MEDEXCEPTION) ;
780 This fonction feeds the FIELD<double> private attributs _value with the
781 barycenter of each faces or cells or edges belonging to the attribut _support.
782 The field has to be initialised via the constructor
783 FIELD<double>(const SUPPORT * ,const int ) with the space dimension has the
784 number of components, and _support has be a SUPPORT on 3D cells or 2D faces.
785 This initialisation could be done by the empty constructor followed by a
786 setSupport and setNumberOfComponents call.
788 void getBarycenter() const throw (MEDEXCEPTION) ;
790 typedef void (*myFuncType)(const double *,T*);
791 void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION);
795 #include "MEDMEM_DriverFactory.hxx"
799 template <class T,class INTERLACING_TAG> T FIELD<T, INTERLACING_TAG>::_scalarForPow=1;
801 // --------------------
802 // Implemented Methods
803 // --------------------
806 Constructor with no parameter, most of the attribut members are set to NULL.
808 template <class T, class INTERLACING_TAG>
809 FIELD<T, INTERLACING_TAG>::FIELD():FIELD_()
811 MESSAGE("Constructeur FIELD sans parametre");
813 //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
814 ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE);
815 FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
817 //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
818 ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE);
819 FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
821 _value = ( ArrayNoGauss * ) NULL;
825 Constructor with parameters such that all attrribut are set but the _value
826 attribut is allocated but not set.
828 template <class T, class INTERLACING_TAG>
829 FIELD<T, INTERLACING_TAG>::FIELD(const SUPPORT * Support,
830 const int NumberOfComponents) throw (MEDEXCEPTION) :
831 FIELD_(Support, NumberOfComponents),_value()
833 BEGIN_OF("FIELD<T>::FIELD(const SUPPORT * Support, const int NumberOfComponents)");
836 //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
837 ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE)
838 FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
840 //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
841 ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE)
842 FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
845 // becarefull about the numbre of gauss point
846 _numberOfValues = Support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
848 catch (MEDEXCEPTION &ex) {
849 MESSAGE("No value defined ! ("<<ex.what()<<")");
851 MESSAGE("FIELD : constructeur : "<< _numberOfValues <<" et "<< NumberOfComponents);
852 if (0<_numberOfValues) {
853 _value = new ArrayNoGauss (_numberOfComponents,_numberOfValues);
857 END_OF("FIELD<T>::FIELD(const SUPPORT * Support, const int NumberOfComponents)");
864 template <class T, class INTERLACING_TAG> void FIELD<T, INTERLACING_TAG>::init ()
871 template <class T, class INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::FIELD(const FIELD & m):
874 MESSAGE("Constructeur FIELD de recopie");
876 // RECOPIE PROFOND Rmq from EF
877 if (m._value != NULL)
879 if ( m.getGaussPresence() )
880 _value = new ArrayGauss( *(dynamic_cast< ArrayGauss * > (m._value) ) ,false);
882 _value = new ArrayNoGauss( *(dynamic_cast< ArrayNoGauss * > (m._value)) ,false);
885 _value = (ArrayNoGauss *) NULL;
887 _valueType = m._valueType;
888 _interlacingType = m._interlacingType;
889 //drivers = m._drivers;
897 template <class T, class INTERLACING_TAG>
898 FIELD<T, INTERLACING_TAG> & FIELD<T, INTERLACING_TAG>::operator=(const FIELD &m)
900 MESSAGE("Appel de FIELD<T>::operator=") ;
901 if ( this == &m) return *this;
904 FIELD_::operator=(m); // Driver are ignored & ?copie su pointeur de Support?
906 _value = m._value; //PROBLEME RECOPIE DES POINTEURS PAS COHERENT AVEC LE
907 //CONSTRUCTEUR PAR RECOPIE
908 //CF :Commentaire dans MEDMEM_Array
909 _valueType = m._valueType;
910 _interlacingType = m._interlacingType;
914 Overload addition operator.
915 This operation is authorized only for compatible fields that have the same support.
916 The compatibility checking includes equality tests of the folowing data members:\n
918 - _numberOfComponents
921 - _MEDComponentsUnits.
923 The data members of the returned field are initialized, based on the first field, except for the name,
924 which is the combination of the two field's names and the operator.
925 Advised Utilisation in C++ : <tt> FIELD<T> c = a + b; </tt> \n
926 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
927 When using python, this operator calls the copy constructor in any case.
928 The user has to be aware that when using operator + in associatives expressions like
929 <tt> a = b + c + d +e; </tt> \n
930 no optimisation is performed : the evaluation of last expression requires the construction of
933 template <class T, class INTERLACING_TAG>
934 const FIELD<T, INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::operator+(const FIELD & m) const
936 BEGIN_OF("FIELD<T>::operator+(const FIELD & m)");
937 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
939 // Creation of the result - memory is allocated by FIELD constructor
940 FIELD<T, INTERLACING_TAG> result(this->getSupport(),this->getNumberOfComponents());
941 //result._operation(*this,m,mode,"+"); // perform Atribute's initialization & addition
942 result._operationInitialize(*this,m,"+"); // perform Atribute's initialization
943 result._add_in_place(*this,m); // perform addition
945 END_OF("FIELD<T>::operator+(const FIELD & m)");
949 /*! Overloaded Operator +=
950 * Operations are directly performed in the first field's array.
951 * This operation is authorized only for compatible fields that have the same support.
953 template <class T, class INTERLACING_TAG>
954 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator+=(const FIELD & m)
956 BEGIN_OF("FIELD<T>::operator+=(const FIELD & m)");
957 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
959 const T* value1=m.getValue(); // get pointers to the values we are adding
961 // get a non const pointer to the inside array of values and perform operation
962 T * value=const_cast<T *> (getValue());
963 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
964 const T* endV=value+size; // pointer to the end of value
965 for(;value!=endV; value1++,value++)
967 END_OF("FIELD<T>::operator+=(const FIELD & m)");
972 /*! Addition of fields. Static member function.
973 * The function return a pointer to a new created field that holds the addition.
974 * Data members are checked for compatibility and initialized.
975 * The user is in charge of memory deallocation.
977 template <class T, class INTERLACING_TAG>
978 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::add(const FIELD& m, const FIELD& n)
980 BEGIN_OF("FIELD<T>::add(const FIELD & m, const FIELD& n)");
981 FIELD_::_checkFieldCompatibility(m, n); // may throw exception
983 // Creation of a new field
984 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
985 m.getNumberOfComponents());
986 result->_operationInitialize(m,n,"+"); // perform Atribute's initialization
987 result->_add_in_place(m,n); // perform addition
989 END_OF("FIELD<T>::add(const FIELD & m, const FIELD& n)");
993 /*! Same as add method except that field check is deeper.
995 template <class T, class INTERLACING_TAG>
996 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::addDeep(const FIELD& m, const FIELD& n)
998 BEGIN_OF("FIELD<T>::addDeep(const FIELD & m, const FIELD& n)");
999 FIELD_::_deepCheckFieldCompatibility(m, n); // may throw exception
1001 // Creation of a new field
1002 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1003 m.getNumberOfComponents());
1004 result->_operationInitialize(m,n,"+"); // perform Atribute's initialization
1005 result->_add_in_place(m,n); // perform addition
1007 END_OF("FIELD<T>::addDeep(const FIELD & m, const FIELD& n)");
1012 Overload substraction operator.
1013 This operation is authorized only for compatible fields that have the same support.
1014 The compatibility checking includes equality tests of the folowing data members:\n
1016 - _numberOfComponents
1019 - _MEDComponentsUnits.
1021 The data members of the returned field are initialized, based on the first field, except for the name,
1022 which is the combination of the two field's names and the operator.
1023 Advised Utilisation in C++ : <tt> FIELD<T> c = a - b; </tt> \n
1024 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1025 When using python, this operator calls the copy constructor in any case.
1026 The user has to be aware that when using operator - in associatives expressions like
1027 <tt> a = b - c - d -e; </tt> \n
1028 no optimisation is performed : the evaluation of last expression requires the construction of
1031 template <class T, class INTERLACING_TAG>
1032 const FIELD<T, INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::operator-(const FIELD & m) const
1034 BEGIN_OF("FIELD<T>::operator-(const FIELD & m)");
1035 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1037 // Creation of the result - memory is allocated by FIELD constructor
1038 FIELD<T, INTERLACING_TAG> result(this->getSupport(),this->getNumberOfComponents());
1039 //result._operation(*this,m,mode,"-"); // perform Atribute's initialization & substraction
1040 result._operationInitialize(*this,m,"-"); // perform Atribute's initialization
1041 result._sub_in_place(*this,m); // perform substracion
1043 END_OF("FIELD<T>::operator-(const FIELD & m)");
1047 template <class T, class INTERLACING_TAG>
1048 const FIELD<T, INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::operator-() const
1050 BEGIN_OF("FIELD<T>::operator-()");
1052 // Creation of the result - memory is allocated by FIELD constructor
1053 FIELD<T, INTERLACING_TAG> result(this->getSupport(),this->getNumberOfComponents());
1054 // Atribute's initialization
1055 result.setName("- "+getName());
1056 result.setComponentsNames(getComponentsNames());
1057 // not yet implemented setComponentType(getComponentType());
1058 result.setComponentsDescriptions(getComponentsDescriptions());
1059 result.setMEDComponentsUnits(getMEDComponentsUnits());
1060 result.setComponentsUnits(getComponentsUnits());
1061 result.setIterationNumber(getIterationNumber());
1062 result.setTime(getTime());
1063 result.setOrderNumber(getOrderNumber());
1065 const T* value1=getValue();
1066 // get a non const pointer to the inside array of values and perform operation
1067 T * value=const_cast<T *> (result.getValue());
1068 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1069 const T* endV=value+size; // pointer to the end of value
1071 for(;value!=endV; value1++,value++)
1072 *value = -(*value1);
1073 END_OF("FIELD<T>::operator-=(const FIELD & m)");
1077 /*! Overloaded Operator -=
1078 * Operations are directly performed in the first field's array.
1079 * This operation is authorized only for compatible fields that have the same support.
1081 template <class T, class INTERLACING_TAG>
1082 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator-=(const FIELD & m)
1084 BEGIN_OF("FIELD<T>::operator-=(const FIELD & m)");
1085 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1087 const T* value1=m.getValue();
1089 // get a non const pointer to the inside array of values and perform operation
1090 T * value=const_cast<T *> (getValue());
1091 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1092 const T* endV=value+size; // pointer to the end of value
1094 for(;value!=endV; value1++,value++)
1097 END_OF("FIELD<T>::operator-=(const FIELD & m)");
1102 /*! Substraction of fields. Static member function.
1103 * The function return a pointer to a new created field that holds the substraction.
1104 * Data members are checked for compatibility and initialized.
1105 * The user is in charge of memory deallocation.
1107 template <class T, class INTERLACING_TAG>
1108 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::sub(const FIELD& m, const FIELD& n)
1110 BEGIN_OF("FIELD<T>::sub(const FIELD & m, const FIELD& n)");
1111 FIELD_::_checkFieldCompatibility(m, n); // may throw exception
1113 // Creation of a new field
1114 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1115 m.getNumberOfComponents());
1116 result->_operationInitialize(m,n,"-"); // perform Atribute's initialization
1117 result->_sub_in_place(m,n); // perform substraction
1119 END_OF("FIELD<T>::sub(const FIELD & m, const FIELD& n)");
1123 /*! Same as sub method except that field check is deeper.
1125 template <class T, class INTERLACING_TAG>
1126 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::subDeep(const FIELD& m, const FIELD& n)
1128 BEGIN_OF("FIELD<T>::subDeep(const FIELD & m, const FIELD& n)");
1129 FIELD_::_deepCheckFieldCompatibility(m, n); // may throw exception
1131 // Creation of a new field
1132 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1133 m.getNumberOfComponents());
1134 result->_operationInitialize(m,n,"-"); // perform Atribute's initialization
1135 result->_sub_in_place(m,n); // perform substraction
1137 END_OF("FIELD<T>::subDeep(const FIELD & m, const FIELD& n)");
1142 Overload multiplication operator.
1143 This operation is authorized only for compatible fields that have the same support.
1144 The compatibility checking includes equality tests of the folowing data members:\n
1146 - _numberOfComponents
1149 - _MEDComponentsUnits.
1151 The data members of the returned field are initialized, based on the first field, except for the name,
1152 which is the combination of the two field's names and the operator.
1153 Advised Utilisation in C++ : <tt> FIELD<T> c = a * b; </tt> \n
1154 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1155 When using python, this operator calls the copy constructor in any case.
1156 The user has to be aware that when using operator * in associatives expressions like
1157 <tt> a = b * c * d *e; </tt> \n
1158 no optimisation is performed : the evaluation of last expression requires the construction of
1161 template <class T, class INTERLACING_TAG>
1162 const FIELD<T, INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::operator*(const FIELD & m) const
1164 BEGIN_OF("FIELD<T>::operator*(const FIELD & m)");
1165 FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1167 // Creation of the result - memory is allocated by FIELD constructor
1168 FIELD<T, INTERLACING_TAG> result(this->getSupport(),this->getNumberOfComponents());
1169 //result._operation(*this,m,mode,"*"); // perform Atribute's initialization & multiplication
1170 result._operationInitialize(*this,m,"*"); // perform Atribute's initialization
1171 result._mul_in_place(*this,m); // perform multiplication
1173 END_OF("FIELD<T>::operator*(const FIELD & m)");
1177 /*! Overloaded Operator *=
1178 * Operations are directly performed in the first field's array.
1179 * This operation is authorized only for compatible fields that have the same support.
1181 template <class T, class INTERLACING_TAG>
1182 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator*=(const FIELD & m)
1184 BEGIN_OF("FIELD<T>::operator*=(const FIELD & m)");
1185 FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1187 const T* value1=m.getValue();
1189 // get a non const pointer to the inside array of values and perform operation
1190 T * value=const_cast<T *> (getValue());
1191 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1192 const T* endV=value+size; // pointer to the end of value
1194 for(;value!=endV; value1++,value++)
1197 END_OF("FIELD<T>::operator*=(const FIELD & m)");
1202 /*! Multiplication of fields. Static member function.
1203 * The function return a pointer to a new created field that holds the multiplication.
1204 * Data members are checked for compatibility and initialized.
1205 * The user is in charge of memory deallocation.
1207 template <class T, class INTERLACING_TAG>
1208 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::mul(const FIELD& m, const FIELD& n)
1210 BEGIN_OF("FIELD<T>::mul(const FIELD & m, const FIELD& n)");
1211 FIELD_::_checkFieldCompatibility(m, n, false); // may throw exception
1213 // Creation of a new field
1214 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1215 m.getNumberOfComponents());
1216 result->_operationInitialize(m,n,"*"); // perform Atribute's initialization
1217 result->_mul_in_place(m,n); // perform multiplication
1219 END_OF("FIELD<T>::mul(const FIELD & m, const FIELD& n)");
1223 /*! Same as mul method except that field check is deeper.
1225 template <class T, class INTERLACING_TAG>
1226 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::mulDeep(const FIELD& m, const FIELD& n)
1228 BEGIN_OF("FIELD<T>::mulDeep(const FIELD & m, const FIELD& n)");
1229 FIELD_::_deepCheckFieldCompatibility(m, n, false); // may throw exception
1231 // Creation of a new field
1232 FIELD<T, INTERLACING_TAG>* result = new FIELD<T,INTERLACING_TAG>(m.getSupport(),
1233 m.getNumberOfComponents());
1234 result->_operationInitialize(m,n,"*"); // perform Atribute's initialization
1235 result->_mul_in_place(m,n); // perform multiplication
1237 END_OF("FIELD<T>::mulDeep(const FIELD & m, const FIELD& n)");
1242 Overload division operator.
1243 This operation is authorized only for compatible fields that have the same support.
1244 The compatibility checking includes equality tests of the folowing data members:\n
1246 - _numberOfComponents
1249 - _MEDComponentsUnits.
1251 The data members of the returned field are initialized, based on the first field, except for the name,
1252 which is the combination of the two field's names and the operator.
1253 Advised Utilisation in C++ : <tt> FIELD<T> c = a / b; </tt> \n
1254 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1255 When using python, this operator calls the copy constructor in any case.
1256 The user has to be aware that when using operator / in associatives expressions like
1257 <tt> a = b / c / d /e; </tt> \n
1258 no optimisation is performed : the evaluation of last expression requires the construction of
1261 template <class T, class INTERLACING_TAG>
1262 const FIELD<T, INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::operator/(const FIELD & m) const
1264 BEGIN_OF("FIELD<T>::operator/(const FIELD & m)");
1265 FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1267 // Creation of the result - memory is allocated by FIELD constructor
1268 FIELD<T, INTERLACING_TAG> result(this->getSupport(),this->getNumberOfComponents());
1269 //result._operation(*this,m,mode,"/"); // perform Atribute's initialization & division
1270 result._operationInitialize(*this,m,"/"); // perform Atribute's initialization
1271 result._div_in_place(*this,m); // perform division
1273 END_OF("FIELD<T>::operator/(const FIELD & m)");
1278 /*! Overloaded Operator /=
1279 * Operations are directly performed in the first field's array.
1280 * This operation is authorized only for compatible fields that have the same support.
1282 template <class T, class INTERLACING_TAG>
1283 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator/=(const FIELD & m)
1285 BEGIN_OF("FIELD<T>::operator/=(const FIELD & m)");
1286 FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1288 const T* value1=m.getValue(); // get pointers to the values we are adding
1290 // get a non const pointer to the inside array of values and perform operation
1291 T * value=const_cast<T *> (getValue());
1292 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1293 const T* endV=value+size; // pointer to the end of value
1295 for(;value!=endV; value1++,value++)
1298 END_OF("FIELD<T>::operator/=(const FIELD & m)");
1303 /*! Division of fields. Static member function.
1304 * The function return a pointer to a new created field that holds the division.
1305 * Data members are checked for compatibility and initialized.
1306 * The user is in charge of memory deallocation.
1308 template <class T, class INTERLACING_TAG>
1309 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::div(const FIELD& m, const FIELD& n)
1311 BEGIN_OF("FIELD<T>::div(const FIELD & m, const FIELD& n)");
1312 FIELD_::_checkFieldCompatibility(m, n, false); // may throw exception
1314 // Creation of a new field
1315 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1316 m.getNumberOfComponents());
1317 result->_operationInitialize(m,n,"/"); // perform Atribute's initialization
1318 result->_div_in_place(m,n); // perform division
1320 END_OF("FIELD<T>::div(const FIELD & m, const FIELD& n)");
1324 /*! Same as div method except that field check is deeper.
1326 template <class T,class INTERLACING_TAG>
1327 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::divDeep(const FIELD& m, const FIELD& n)
1329 BEGIN_OF("FIELD<T>::divDeep(const FIELD & m, const FIELD& n)");
1330 FIELD_::_deepCheckFieldCompatibility(m, n, false); // may throw exception
1332 // Creation of a new field
1333 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1334 m.getNumberOfComponents());
1335 result->_operationInitialize(m,n,"/"); // perform Atribute's initialization
1336 result->_div_in_place(m,n); // perform division
1338 END_OF("FIELD<T>::divDeep(const FIELD & m, const FIELD& n)");
1344 This internal method initialize the members of a new field created to hold the result of the operation Op .
1345 Initialization is based on the first field, except for the name, which is the combination of the two field's names
1349 template <class T, class INTERLACING_TAG>
1350 void FIELD<T, INTERLACING_TAG>::_operationInitialize(const FIELD& m,const FIELD& n, char* Op)
1352 MESSAGE("Appel methode interne " << Op);
1354 // Atribute's initialization (copy of the first field's attributes)
1355 // Other data members (_support, _numberOfValues) are initialized in the field's constr.
1356 setName(m.getName()+" "+Op+" "+n.getName());
1357 setComponentsNames(m.getComponentsNames());
1358 // not yet implemented setComponentType(m.getComponentType());
1359 setComponentsDescriptions(m.getComponentsDescriptions());
1360 setMEDComponentsUnits(m.getMEDComponentsUnits());
1362 // The following data member may differ from field m to n.
1363 // The initialization is done based on the first field.
1365 if(m.getComponentsUnits() != NULL)
1366 setComponentsUnits(m.getComponentsUnits());
1368 _componentsUnits = (UNIT *) NULL;
1370 setIterationNumber(m.getIterationNumber());
1371 setTime(m.getTime());
1372 setOrderNumber(m.getOrderNumber());
1378 Internal method called by FIELD<T>::operator+ and FIELD<T>::add to perform addition "in place".
1379 This method is applied to a just created field with medModeSwitch mode.
1380 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1384 template <class T, class INTERLACING_TAG>
1385 void FIELD<T, INTERLACING_TAG>::_add_in_place(const FIELD& m,const FIELD& n)
1387 // get pointers to the values we are adding
1388 const T* value1=m.getValue();
1389 const T* value2=n.getValue();
1390 // get a non const pointer to the inside array of values and perform operation
1391 T * value=const_cast<T *> (getValue());
1393 const int size=getNumberOfValues()*getNumberOfComponents();
1395 const T* endV1=value1+size;
1396 for(;value1!=endV1; value1++,value2++,value++)
1397 *value=(*value1)+(*value2);
1402 Internal method called by FIELD<T>::operator- and FIELD<T>::sub to perform substraction "in place".
1403 This method is applied to a just created field with medModeSwitch mode.
1404 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1408 template <class T, class INTERLACING_TAG>
1409 void FIELD<T, INTERLACING_TAG>::_sub_in_place(const FIELD& m,const FIELD& n)
1411 // get pointers to the values we are adding
1412 const T* value1=m.getValue();
1413 const T* value2=n.getValue();
1414 // get a non const pointer to the inside array of values and perform operation
1415 T * value=const_cast<T *> (getValue());
1417 const int size=getNumberOfValues()*getNumberOfComponents();
1419 const T* endV1=value1+size;
1420 for(;value1!=endV1; value1++,value2++,value++)
1421 *value=(*value1)-(*value2);
1426 Internal method called by FIELD<T>::operator* and FIELD<T>::mul to perform multiplication "in place".
1427 This method is applied to a just created field with medModeSwitch mode.
1428 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1432 template <class T, class INTERLACING_TAG>
1433 void FIELD<T, INTERLACING_TAG>::_mul_in_place(const FIELD& m,const FIELD& n)
1435 // get pointers to the values we are adding
1436 const T* value1=m.getValue();
1437 const T* value2=n.getValue();
1438 // get a non const pointer to the inside array of values and perform operation
1439 T * value=const_cast<T *> (getValue());
1441 const int size=getNumberOfValues()*getNumberOfComponents();
1443 const T* endV1=value1+size;
1444 for(;value1!=endV1; value1++,value2++,value++)
1445 *value=(*value1)*(*value2);
1450 Internal method called by FIELD<T>::operator/ and FIELD<T>::div to perform division "in place".
1451 This method is applied to a just created field with medModeSwitch mode.
1452 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1456 template <class T, class INTERLACING_TAG>
1457 void FIELD<T, INTERLACING_TAG>::_div_in_place(const FIELD& m,const FIELD& n) throw (MEDEXCEPTION)
1459 // get pointers to the values we are adding
1460 const T* value1=m.getValue();
1461 const T* value2=n.getValue();
1462 // get a non const pointer to the inside array of values and perform operation
1463 T * value=const_cast<T *> (getValue());
1465 const int size=getNumberOfValues()*getNumberOfComponents();
1467 const T* endV1=value1+size;
1468 for(;value1!=endV1; value1++,value2++,value++){
1469 if ( *value2 == 0 ) { // FAIRE PLUTOT UN TRY CATCH Rmq from EF
1471 diagnosis="FIELD<T,INTERLACING_TAG>::_div_in_place(...) : Divide by zero !";
1472 throw MEDEXCEPTION(diagnosis.c_str());
1474 *value=(*value1)/(*value2);
1480 template <class T, class INTERLACIN_TAG> double FIELD<T, INTERLACIN_TAG>::normMax() const throw (MEDEXCEPTION)
1482 const T* value=getValue(); // get pointer to the values
1483 const int size=getNumberOfValues()*getNumberOfComponents();
1484 if (size <= 0) // Size of array has to be strictly positive
1487 diagnosis="FIELD<T,INTERLACIN_TAG>::normMax() : cannot compute the norm of "+getName()+
1488 " : it size is non positive!";
1489 throw MEDEXCEPTION(diagnosis.c_str());
1491 const T* lastvalue=value+size; // get pointer just after last value
1492 const T* pMax=value; // pointer to the max value
1493 const T* pMin=value; // pointer to the min value
1495 // get pointers to the max & min value of array
1496 while ( ++value != lastvalue )
1498 if ( *pMin > *value )
1500 if ( *pMax < *value )
1504 T Max= *pMax>(T) 0 ? *pMax : -*pMax; // Max=abs(*pMax)
1505 T Min= *pMin>(T) 0 ? *pMin : -*pMin; // Min=abs(*pMin)
1507 return Max>Min ? static_cast<double>(Max) : static_cast<double>(Min);
1510 /*! Return Euclidien norm
1512 template <class T, class INTERLACIN_TAG> double FIELD<T, INTERLACIN_TAG>::norm2() const throw (MEDEXCEPTION)
1514 const T* value=this->getValue(); // get const pointer to the values
1515 const int size=getNumberOfValues()*getNumberOfComponents(); // get size of array
1516 if (size <= 0) // Size of array has to be strictly positive
1519 diagnosis="FIELD<T,INTERLACIN_TAG>::norm2() : cannot compute the norm of "+getName()+
1520 " : it size is non positive!";
1521 throw MEDEXCEPTION(diagnosis.c_str());
1523 const T* lastvalue=value+size; // point just after last value
1525 T result((T)0); // init
1526 for( ; value!=lastvalue ; ++value)
1527 result += (*value) * (*value);
1529 return std::sqrt(static_cast<double> (result));
1533 /*! Apply to each (scalar) field component the template parameter T_function,
1534 * which is a pointer to function.
1535 * Since the pointer is known at compile time, the function is inlined into the inner loop!
1536 * calculation is done "in place".
1539 * \code myField.applyFunc<std::sqrt>(); // apply sqare root function \endcode
1540 * \code myField.applyFunc<myFunction>(); // apply your own created function \endcode
1542 template <class T, class INTERLACIN_TAG> template <T T_function(T)>
1543 void FIELD<T, INTERLACIN_TAG>::applyFunc()
1545 // get a non const pointer to the inside array of values and perform operation
1546 T * value=const_cast<T *> (getValue());
1547 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1549 if (size>0) // for a negative size, there is nothing to do
1551 const T* lastvalue=value+size; // pointer to the end of value
1552 for(;value!=lastvalue; ++value) // apply linear transformation
1553 *value = T_function(*value);
1557 template <class T, class INTERLACIN_TAG> T FIELD<T, INTERLACIN_TAG>::pow(T x)
1559 return (T)::pow(x,FIELD<T, INTERLACIN_TAG>::_scalarForPow);
1562 /*! Apply to each (scalar) field component the math function pow.
1563 * calculation is done "in place".
1566 * \code myField.applyFunc<std::sqrt>(); // apply sqare root function \endcode
1567 * \code myField.applyFunc<myFunction>(); // apply your own created function \endcode
1569 template <class T, class INTERLACIN_TAG> void FIELD<T, INTERLACIN_TAG>::applyPow(T scalar)
1571 FIELD<T, INTERLACIN_TAG>::_scalarForPow=scalar;
1572 applyFunc<FIELD<T, INTERLACIN_TAG>::pow>();
1575 /*! Apply to each (scalar) field component the linear function x -> ax+b.
1576 * calculation is done "in place".
1578 template <class T, class INTERLACIN_TAG> void FIELD<T, INTERLACIN_TAG>::applyLin(T a, T b)
1580 // get a non const pointer to the inside array of values and perform operation in place
1581 T * value=const_cast<T *> (getValue());
1582 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1584 if (size>0) // for a negative size, there is nothing to do
1586 const T* lastvalue=value+size; // pointer to the end of value
1587 for(;value!=lastvalue; ++value) // apply linear transformation
1588 *value = a*(*value)+b;
1594 * Return a pointer to a new field that holds the scalar product. Static member function.
1595 * This operation is authorized only for compatible fields that have the same support.
1596 * The compatibility checking includes equality tests of the folowing data members:\n
1598 * - _numberOfComponents
1600 * - _componentsTypes
1601 * - _MEDComponentsUnits.
1602 * Data members are initialized.
1603 * The new field point to the same support and has one component.
1604 * Each value of it is the scalar product of the two argument's fields.
1605 * The user is in charge of memory deallocation.
1607 template <class T, class INTERLACING_TAG>
1608 FIELD<T, INTERLACING_TAG>*
1609 FIELD<T, INTERLACING_TAG>::scalarProduct(const FIELD & m, const FIELD & n, bool deepCheck)
1612 FIELD_::_checkFieldCompatibility( m, n, false); // may throw exception
1614 FIELD_::_deepCheckFieldCompatibility(m, n, false);
1616 // we need a MED_FULL_INTERLACE representation of m & n to compute the scalar product
1617 // result type imply INTERLACING_TAG=FullInterlace for m & n
1619 const int numberOfElements=m.getNumberOfValues(); // strictly positive
1620 const int NumberOfComponents=m.getNumberOfComponents(); // strictly positive
1622 // Creation & init of a the result field on the same support, with one component
1623 // You have to be careful about the interlacing mode, because in the computation step,
1624 // it seems to assume the the interlacing mode is the FullInterlacing
1626 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),1);
1627 result->setName( "scalarProduct ( " + m.getName() + " , " + n.getName() + " )" );
1628 result->setIterationNumber(m.getIterationNumber());
1629 result->setTime(m.getTime());
1630 result->setOrderNumber(m.getOrderNumber());
1632 const T* value1=m.getValue(); // get const pointer to the values
1633 const T* value2=n.getValue(); // get const pointer to the values
1634 // get a non const pointer to the inside array of values and perform operation
1635 T * value=const_cast<T *> (result->getValue());
1637 const T* lastvalue=value+numberOfElements; // pointing just after last value of result
1638 for ( ; value!=lastvalue ; ++value ) // loop on all elements
1640 *value=(T)0; // initialize value
1641 const T* endofRow=value1+NumberOfComponents; // pointing just after end of row
1642 for ( ; value1 != endofRow; ++value1, ++value2) // computation of dot product
1643 *value += (*value1) * (*value2);
1648 /*! Return L2 Norm of the field's component.
1649 * Cannot be applied to a field with a support on nodes.
1650 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1652 template <class T, class INTERLACING_TAG>
1653 double FIELD<T, INTERLACING_TAG>::normL2(int component,
1654 const FIELD<double, FullInterlace> * p_field_volume) const
1656 _checkNormCompatibility(p_field_volume); // may throw exception
1657 if ( component<1 || component>getNumberOfComponents() )
1658 throw MEDEXCEPTION(STRING("FIELD<T>::normL2() : The component argument should be between 1 and the number of components"));
1660 const FIELD<double, FullInterlace> * p_field_size=p_field_volume;
1661 if(!p_field_volume) // if the user don't supply the volume
1662 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1664 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1665 const double* vol=p_field_size->getValue();
1666 // Il n'est vraiment pas optimal de mixer des champs dans des modes d'entrelacement
1667 // different juste pour le calcul
1669 const T * value = NULL;
1670 ArrayNo * myArray = NULL;
1671 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
1674 myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
1675 value = myArray->getPtr();
1678 const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column
1680 double integrale=0.0;
1682 for (; value!=lastvalue ; ++value ,++vol)
1684 integrale += static_cast<double>((*value) * (*value)) * (*vol);
1688 if(!p_field_volume) // if the user didn't supply the volume
1689 delete p_field_size; // delete temporary volume field
1690 if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
1692 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1694 return integrale/totVol;
1697 /*! Return L2 Norm of the field.
1698 * Cannot be applied to a field with a support on nodes.
1699 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1701 template <class T, class INTERLACING_TAG>
1702 double FIELD<T, INTERLACING_TAG>::normL2(const FIELD<double, FullInterlace> * p_field_volume) const
1704 _checkNormCompatibility(p_field_volume); // may throw exception
1705 const FIELD<double, FullInterlace> * p_field_size=p_field_volume;
1706 if(!p_field_volume) // if the user don't supply the volume
1707 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1709 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1710 const double* vol=p_field_size->getValue();
1711 const double* lastvol=vol+getNumberOfValues(); // pointing just after the end of vol
1713 const T * value = NULL;
1714 ArrayNo * myArray = NULL;
1715 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
1718 myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
1719 value = myArray->getPtr();
1723 const double* p_vol=vol;
1724 for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume
1727 double integrale=0.0;
1728 for (int i=1; i<=getNumberOfComponents(); ++i) // compute integral on all components
1729 for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol)
1730 integrale += static_cast<double>((*value) * (*value)) * (*p_vol);
1732 if(!p_field_volume) // if the user didn't supply the volume
1733 delete p_field_size; // delete temporary volume field
1734 if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
1736 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1738 return integrale/totVol;
1741 /*! Return L1 Norm of the field's component.
1742 * Cannot be applied to a field with a support on nodes.
1743 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1745 template <class T, class INTERLACING_TAG>
1746 double FIELD<T, INTERLACING_TAG>::normL1(int component,
1747 const FIELD<double, FullInterlace > * p_field_volume) const
1749 _checkNormCompatibility(p_field_volume); // may throw exception
1750 if ( component<1 || component>getNumberOfComponents() )
1751 throw MEDEXCEPTION(STRING("FIELD<T,INTERLACING_TAG>::normL2() : The component argument should be between 1 and the number of components"));
1753 const FIELD<double,FullInterlace> * p_field_size=p_field_volume;
1754 if(!p_field_volume) // if the user don't supply the volume
1755 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1757 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1758 const double* vol=p_field_size->getValue();
1759 const T * value = NULL;
1760 ArrayNo * myArray = NULL;
1761 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
1762 value = getColumn(component);
1764 myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
1765 value = myArray->getColumn(component);
1768 const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column
1770 double integrale=0.0;
1772 for (; value!=lastvalue ; ++value ,++vol)
1774 integrale += std::abs( static_cast<double>(*value) ) * (*vol);
1778 if(!p_field_volume) // if the user didn't supply the volume
1779 delete p_field_size; // delete temporary volume field
1780 if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
1782 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1784 return integrale/totVol;
1787 /*! Return L1 Norm of the field.
1788 * Cannot be applied to a field with a support on nodes.
1789 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1791 template <class T, class INTERLACING_TAG>
1792 double FIELD<T, INTERLACING_TAG>::normL1(const FIELD<double, FullInterlace> * p_field_volume) const
1794 _checkNormCompatibility(p_field_volume); // may throw exception
1795 const FIELD<double, FullInterlace> * p_field_size=p_field_volume;
1796 if(!p_field_volume) // if the user don't supply the volume
1797 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1799 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1800 const double* vol=p_field_size->getValue();
1801 const double* lastvol=vol+getNumberOfValues(); // pointing just after the end of vol
1803 const T * value = NULL;
1804 ArrayNo * myArray = NULL;
1805 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
1808 myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
1809 value = myArray->getPtr();
1813 const double* p_vol=vol;
1814 for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume
1817 double integrale=0.0;
1818 for (int i=1; i<=getNumberOfComponents(); ++i) // compute integral on all components
1819 for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol)
1820 integrale += std::abs( static_cast<double>(*value) ) * (*p_vol);
1822 if(!p_field_volume) // if the user didn't supply the volume
1823 delete p_field_size; // delete temporary volume field
1824 if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
1826 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1828 return integrale/totVol;
1831 /*! Return a new field (to deallocate with delete) lying on subSupport that is included by
1832 * this->_support with corresponding values extracting from this->_value.
1834 template <class T, class INTERLACING_TAG>
1835 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION)
1837 if(!subSupport->belongsTo(*_support))
1838 throw MEDEXCEPTION("FIELD<T>::extract : subSupport not included in this->_support !");
1839 if(_support->isOnAllElements() && subSupport->isOnAllElements())
1840 return new FIELD<T, INTERLACING_TAG>(*this);
1842 FIELD<T, INTERLACING_TAG> *ret = new FIELD<T, INTERLACING_TAG>(subSupport,
1843 _numberOfComponents);
1846 throw MEDEXCEPTION("FIELD<T>::extract : unvalid support detected !");
1848 T* valuesToSet=(T*)ret->getValue();
1850 int nbOfEltsSub=subSupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
1851 const int *eltsSub=subSupport->getNumber(MED_EN::MED_ALL_ELEMENTS);
1852 T* tempVals=new T[_numberOfComponents];
1853 for(int i=0;i<nbOfEltsSub;i++)
1855 if(!getValueOnElement(eltsSub[i],tempVals))
1856 throw MEDEXCEPTION("Problem in belongsTo function !!!");
1857 for(int j=0;j<_numberOfComponents;j++)
1858 valuesToSet[i*_numberOfComponents+j]=tempVals[j];
1862 ret->copyGlobalInfo(*this);
1867 Constructor with parameters; the object is set via a file and its associated
1868 driver. For the moment only the MED_DRIVER is considered and if the last two
1869 argument (iterationNumber and orderNumber) are not set; their default value
1870 is -1. If the field fieldDriverName with the iteration number
1871 iterationNumber and the order number orderNumber does not exist in the file
1872 fieldDriverName; the constructor raises an exception.
1874 template <class T, class INTERLACING_TAG>
1875 FIELD<T, INTERLACING_TAG>::FIELD(const SUPPORT * Support,
1876 driverTypes driverType,
1877 const string & fileName/*=""*/,
1878 const string & fieldDriverName/*=""*/,
1879 const int iterationNumber,
1880 const int orderNumber) throw (MEDEXCEPTION)
1882 const char * LOC = "template <class T> FIELD<T>::FIELD(const SUPPORT * Support, driverTypes driverType, const string & fileName=\"\", const string & fieldName=\"\", const int iterationNumber=-1, const int orderNumber=-1) : ";
1890 //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
1891 ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE)
1892 FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
1894 //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
1895 ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE)
1896 FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
1899 //A.G. Addings for RC
1901 _support->addReference();
1902 _value = (MEDMEM_Array<T, INTERLACING_TAG> *) NULL;
1904 _iterationNumber = iterationNumber;
1906 _orderNumber = orderNumber;
1908 current = addDriver(driverType,fileName,fieldDriverName,MED_EN::MED_LECT);
1910 _drivers[current]->open();
1911 _drivers[current]->read();
1912 _drivers[current]->close();
1918 This constructor, at least, allows to create a FIELD without creating any
1919 SUPPORT then without having to load a MESH object, a support is created. It
1920 provides the meshName related mesh but doesn't not set a mesh in the created
1923 template <class T, class INTERLACING_TAG>
1924 FIELD<T,INTERLACING_TAG>::FIELD(driverTypes driverType,
1925 const string & fileName,
1926 const string & fieldDriverName,
1927 const int iterationNumber,
1928 const int orderNumber)
1929 throw (MEDEXCEPTION) :FIELD_()
1932 const char * LOC ="FIELD<T,INTERLACING_TAG>::FIELD( driverTypes driverType, const string & fileName, string & fieldDriverName, int iterationNumber, int orderNumber) : ";
1937 //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
1938 ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE)
1939 FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
1941 //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
1942 ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE)
1943 FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
1945 _support = (SUPPORT *) NULL;
1946 _value = (MEDMEM_Array<T,INTERLACING_TAG> *)NULL;
1948 _iterationNumber = iterationNumber;
1950 _orderNumber = orderNumber;
1952 current = addDriver(driverType,fileName,fieldDriverName,MED_EN::MED_LECT);
1954 _drivers[current]->open();
1955 _drivers[current]->read();
1956 _drivers[current]->close();
1964 template <class T, class INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::~FIELD()
1966 BEGIN_OF(" Destructeur FIELD<T, INTERLACING_TAG>::~FIELD()");
1968 if (_value) delete _value;
1969 END_OF(" Destructeur FIELD<T,INTERLACING_TAG>::~FIELD()");
1975 template <class T, class INTERLACING_TAG>
1976 void FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents)
1978 const char* LOC = "FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents)" ;
1981 _numberOfComponents = NumberOfComponents ;
1982 if (_componentsTypes == NULL)
1983 _componentsTypes = new int[NumberOfComponents] ;
1984 if (_componentsNames == NULL)
1985 _componentsNames = new string[NumberOfComponents];
1986 if (_componentsDescriptions == NULL)
1987 _componentsDescriptions = new string[NumberOfComponents];
1988 if (_componentsUnits == NULL)
1989 _componentsUnits = new UNIT[NumberOfComponents];
1990 if (_MEDComponentsUnits == NULL)
1991 _MEDComponentsUnits = new string[NumberOfComponents];
1992 for (int i=0;i<NumberOfComponents;i++) {
1993 _componentsTypes[i] = 0 ;
1997 // becarefull about the number of gauss point
1998 _numberOfValues = _support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
1999 MESSAGE(LOC <<" : "<<_numberOfValues <<" et "<< NumberOfComponents);
2001 //EF : A modifier lors de l'intégration de la classe de localisation des points de gauss
2002 _value = new ArrayNoGauss(_numberOfComponents,_numberOfValues);
2006 catch (MEDEXCEPTION &ex) {
2007 MESSAGE("No value defined, problem with NumberOfComponents (and may be _support) size of MEDARRAY<T>::_value !");
2008 _value = (MEDMEM_Array<T, INTERLACING_TAG> *)NULL ;
2012 END_OF("void FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents)");
2018 template <class T, class INTERLACING_TAG>
2019 void FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents,
2020 const int LengthValue)
2022 BEGIN_OF("void FIELD<T>::allocValue(const int NumberOfComponents,const int LengthValue)");
2024 _numberOfComponents = NumberOfComponents ;
2025 if (_componentsTypes == NULL)
2026 _componentsTypes = new int[NumberOfComponents] ;
2027 if (_componentsNames == NULL)
2028 _componentsNames = new string[NumberOfComponents];
2029 if (_componentsDescriptions == NULL)
2030 _componentsDescriptions = new string[NumberOfComponents];
2031 if (_componentsUnits == NULL)
2032 _componentsUnits = new UNIT[NumberOfComponents];
2033 if (_MEDComponentsUnits == NULL)
2034 _MEDComponentsUnits = new string[NumberOfComponents];
2035 for (int i=0;i<NumberOfComponents;i++) {
2036 _componentsTypes[i] = 0 ;
2039 MESSAGE("FIELD : constructeur : "<<LengthValue <<" et "<< NumberOfComponents);
2040 _numberOfValues = LengthValue ;
2042 //EF : A modifier lors de l'intégration de la classe de localisation des points de gauss
2043 _value = new ArrayNoGauss(_numberOfComponents,_numberOfValues);
2048 END_OF("void FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents,const int LengthValue)");
2054 template <class T, class INTERLACING_TAG>
2055 void FIELD<T, INTERLACING_TAG>::deallocValue()
2057 BEGIN_OF("void FIELD<T, INTERLACING_TAG>::deallocValue()");
2058 _numberOfValues = 0 ;
2059 _numberOfComponents = 0 ;
2063 END_OF("void FIELD<T, INTERLACING_TAG>::deallocValue()");
2066 // -----------------
2068 // -----------------
2071 Create the specified driver and return its index reference to path to
2072 read or write methods.
2075 template <class T, class INTERLACING_TAG>
2076 int FIELD<T, INTERLACING_TAG>::addDriver(driverTypes driverType,
2077 const string & fileName/*="Default File Name.med"*/,
2078 const string & driverName/*="Default Field Name"*/,
2079 MED_EN::med_mode_acces access)
2081 //jfa tmp (as last argument has no default value):const char * LOC = "FIELD<T>::addDriver(driverTypes driverType, const string & fileName=\"Default File Name.med\",const string & driverName=\"Default Field Name\",MED_EN::med_mode_acces access) : ";
2082 const char * LOC = "FIELD<T>::addDriver(driverTypes driverType, const string & fileName,const string & driverName,MED_EN::med_mode_acces access) :";//jfa tmp
2090 driver = DRIVERFACTORY::buildDriverForField(driverType,fileName,this,access);
2092 _drivers.push_back(driver);
2094 int current = _drivers.size()-1;
2096 _drivers[current]->setFieldName(driverName);
2105 Duplicate the given driver and return its index reference to path to
2106 read or write methods.
2108 template <class T, class INTERLACING_TAG>
2109 inline int FIELD<T, INTERLACING_TAG>::addDriver (GENDRIVER & driver )
2111 const char * LOC = "FIELD<T, INTERLACING_TAG>::addDriver(GENDRIVER &) : ";
2116 // duplicate driver to delete it with destructor !
2117 GENDRIVER * newDriver = driver.copy() ;
2119 _drivers.push_back(newDriver);
2121 current = _drivers.size()-1;
2123 driver.setId(current);
2125 MESSAGE(LOC << " je suis la 1");
2127 MESSAGE(LOC << " je suis la 2");
2133 Remove the driver referenced by its index.
2135 template <class T, class INTERLACING_TAG>
2136 void FIELD<T, INTERLACING_TAG>::rmDriver (int index/*=0*/)
2138 const char * LOC = "FIELD<T, INTERLACING_TAG>::rmDriver (int index=0): ";
2141 if ( _drivers[index] ) {
2142 //_drivers.erase(&_drivers[index]);
2144 MESSAGE ("detruire");
2147 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
2148 << "The <index given is invalid, index must be between 0 and |"
2157 Read FIELD in the file specified in the driver given by its index.
2159 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::read(int index/*=0*/)
2161 const char * LOC = "FIELD<T, INTERLACING_TAG>::read(int index=0) : ";
2164 if ( _drivers[index] ) {
2165 _drivers[index]->open();
2166 _drivers[index]->read();
2167 _drivers[index]->close();
2170 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
2171 << "The index given is invalid, index must be between 0 and |"
2179 Write FIELD in the file specified in the driver given by its index.
2181 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::write(int index/*=0*/, const string & driverName /*= ""*/)
2183 const char * LOC = "FIELD<T,INTERLACING_TAG>::write(int index=0, const string & driverName = \"\") : ";
2186 if( _drivers[index] ) {
2187 _drivers[index]->open();
2188 if (driverName != "") _drivers[index]->setFieldName(driverName);
2189 _drivers[index]->write();
2190 _drivers[index]->close();
2193 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
2194 << "The index given is invalid, index must be between 0 and |"
2202 Write FIELD in the file specified in the driver given by its index. Use this
2203 method for ASCII drivers (e.g. VTK_DRIVER)
2205 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::writeAppend(int index/*=0*/, const string & driverName /*= ""*/)
2207 const char * LOC = "FIELD<T,INTERLACING_TAG>::write(int index=0, const string & driverName = \"\") : ";
2210 if( _drivers[index] ) {
2211 _drivers[index]->openAppend();
2212 if (driverName != "") _drivers[index]->setFieldName(driverName);
2213 _drivers[index]->writeAppend();
2214 _drivers[index]->close();
2217 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
2218 << "The index given is invalid, index must be between 0 and |"
2227 Write FIELD with the driver which is equal to the given driver.
2231 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::write(const GENDRIVER & genDriver)
2233 const char * LOC = " FIELD<T, INTERLACING_TAG>::write(const GENDRIVER &) : ";
2236 for (unsigned int index=0; index < _drivers.size(); index++ )
2237 if ( *_drivers[index] == genDriver ) {
2238 _drivers[index]->open();
2239 _drivers[index]->write();
2240 _drivers[index]->close();
2249 Write FIELD with the driver which is equal to the given driver.
2251 Use by MED object. Use this method for ASCII drivers (e.g. VTK_DRIVER).
2253 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::writeAppend(const GENDRIVER & genDriver)
2255 const char * LOC = " FIELD<T, INTERLACING_TAG>::write(const GENDRIVER &) : ";
2258 for (unsigned int index=0; index < _drivers.size(); index++ )
2259 if ( *_drivers[index] == genDriver ) {
2260 _drivers[index]->openAppend();
2261 _drivers[index]->writeAppend();
2262 _drivers[index]->close();
2271 Read FIELD with the driver which is equal to the given driver.
2275 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::read(const GENDRIVER & genDriver)
2277 const char * LOC = " FIELD<T, INTERLACING_TAG>::read(const GENDRIVER &) : ";
2280 for (unsigned int index=0; index < _drivers.size(); index++ )
2281 if ( *_drivers[index] == genDriver ) {
2282 _drivers[index]->open();
2283 _drivers[index]->read();
2284 _drivers[index]->close();
2292 Fills in already allocated retValues array the values related to eltIdInSup.
2293 If the element does not exist in this->_support false is returned, true otherwise.
2295 template <class T, class INTERLACING_TAG>
2296 bool FIELD<T, INTERLACING_TAG>::getValueOnElement(int eltIdInSup,T* retValues)
2297 const throw (MEDEXCEPTION)
2299 // retValues = getRow(eltIdInSup);
2303 if(_support->isOnAllElements())
2305 int nbOfEltsThis=_support->getMesh()->getNumberOfElements(_support->getEntity(),MED_EN::MED_ALL_ELEMENTS);
2306 if(eltIdInSup>nbOfEltsThis)
2308 const T* valsThis=getValue();
2309 for(int j=0;j<_numberOfComponents;j++)
2310 retValues[j]=valsThis[(eltIdInSup-1)*_numberOfComponents+j];
2315 int nbOfEltsThis=_support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
2316 const int *eltsThis=_support->getNumber(MED_EN::MED_ALL_ELEMENTS);
2319 for(iThis=0;iThis<nbOfEltsThis && !found;)
2320 if(eltsThis[iThis]==eltIdInSup)
2326 const T* valsThis=getValue();
2327 for(int j=0;j<_numberOfComponents;j++)
2328 retValues[j]=valsThis[iThis*_numberOfComponents+j];
2335 Destroy the MEDARRAY<T> in FIELD and put the new one without copy.
2338 template <class T, class INTERLACING_TAG>
2339 inline void FIELD<T, INTERLACING_TAG>::setArray(MEDMEM_Array_ * Value)
2340 throw (MEDEXCEPTION)
2342 if (NULL != _value) delete _value ;
2348 Return a reference to the MEDARRAY<T, INTERLACING_TAG> in FIELD.
2351 template <class T, class INTERLACING_TAG>
2352 inline MEDMEM_Array_ * FIELD<T, INTERLACING_TAG>::getArray() const throw (MEDEXCEPTION)
2354 const char * LOC = "MEDMEM_Array_ * FIELD<T, INTERLACING_TAG>::getArray() : ";
2359 template <class T,class INTERLACING_TAG> inline
2360 typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,Gauss>::Array *
2361 FIELD<T, INTERLACING_TAG>::getArrayGauss() const throw (MEDEXCEPTION)
2363 const char * LOC = "FIELD<T, INTERLACING_TAG>::getArrayGauss() : ";
2366 if ( getGaussPresence() )
2367 return dynamic_cast<ArrayGauss *> (_value);
2369 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<
2370 "The field has no Gauss Point"));
2376 template <class T,class INTERLACING_TAG> inline
2377 typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,NoGauss>::Array *
2378 FIELD<T, INTERLACING_TAG>::getArrayNoGauss() const throw (MEDEXCEPTION)
2380 const char * LOC = "FIELD<T, INTERLACING_TAG>::getArrayNoGauss() : ";
2383 if ( ! getGaussPresence() )
2384 return dynamic_cast < ArrayNoGauss * > (_value);
2386 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<
2387 "The field has Gauss Point"));
2393 template <class T,class INTERLACING_TAG> inline bool
2394 FIELD<T, INTERLACING_TAG>::getGaussPresence() const throw (MEDEXCEPTION)
2396 const char * LOC = "FIELD<T, INTERLACING_TAG>::getGaussPresence() const :";
2400 return _value->getGaussPresence();
2402 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't call getGaussPresence on a null _value"));
2408 Return the actual length of the reference to values array returned by getValue.
2410 template <class T, class INTERLACING_TAG>
2411 inline int FIELD<T, INTERLACING_TAG>::getValueLength() const
2412 throw (MEDEXCEPTION)
2414 // be carefull about number of gauss point
2415 return _numberOfComponents*_numberOfValues;
2419 Return a reference to values array to read them.
2421 template <class T, class INTERLACIN_TAG>
2422 inline const T* FIELD<T, INTERLACIN_TAG>::getValue() const throw (MEDEXCEPTION)
2424 const char * LOC ="FIELD<T, INTERLACING_TAG>::getValue() : ";
2426 if ( getGaussPresence() )
2427 return dynamic_cast<ArrayGauss *>(_value)->getPtr() ;
2429 return dynamic_cast<ArrayNoGauss *>(_value)->getPtr() ;
2432 Return a reference to i^{th} row
2433 of FIELD values array.
2434 If a faster accessor is intended you may use getArray() once,
2435 then MEDMEM_Array accessors.
2436 Be careful if field support is not on all elements you might
2437 have to use support->getValIndFromGlobalNumber(i).
2439 template <class T,class INTERLACING_TAG> inline
2441 FIELD<T,INTERLACING_TAG>::getRow(int i) const throw (MEDEXCEPTION)
2443 const char * LOC = "FIELD<T,INTERLACING_TAG>::getRow(int i) : ";
2448 valIndex = _support->getValIndFromGlobalNumber(i);
2450 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
2452 if ( getGaussPresence() )
2453 return dynamic_cast<ArrayGauss *>(_value)->getRow(valIndex) ;
2455 return dynamic_cast<ArrayNoGauss *>(_value)->getRow(valIndex) ;
2460 Return a reference to j^{th} column
2461 of FIELD values array.
2463 template <class T,class INTERLACING_TAG> inline const T*
2464 FIELD<T,INTERLACING_TAG>::getColumn(int j) const throw (MEDEXCEPTION)
2466 const char * LOC ="FIELD<T,INTERLACING_TAG>::getColumn(int j) : ";
2468 if ( getGaussPresence() )
2469 return dynamic_cast<ArrayGauss *>(_value)->getColumn(j) ;
2471 return dynamic_cast<ArrayNoGauss *>(_value)->getColumn(j) ;
2475 Return the value of i^{th} element and j^{th} component.
2477 template <class T,class INTERLACING_TAG> inline T FIELD<T,INTERLACING_TAG>::getValueIJ(int i,int j) const throw (MEDEXCEPTION)
2479 const char * LOC = "getValueIJ(..)";
2483 valIndex = _support->getValIndFromGlobalNumber(i);
2485 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
2487 if ( getGaussPresence() )
2488 return dynamic_cast<ArrayGauss *>(_value)->getIJ(valIndex,j) ;
2490 return dynamic_cast<ArrayNoGauss *>(_value)->getIJ(valIndex,j) ;
2494 Copy new values array in FIELD according to the given mode.
2496 Array must have right size. If not results are unpredicable.
2498 template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValue( T* value) throw (MEDEXCEPTION)
2500 if ( getGaussPresence() )
2501 return dynamic_cast<ArrayGauss *>(_value)->setPtr(value) ;
2503 return dynamic_cast<ArrayNoGauss *>(_value)->setPtr(value) ;
2507 Update values array in the j^{th} row of FIELD values array with the given ones and
2508 according to specified mode.
2510 template <class T,class INTERLACING_TAG>
2511 inline void FIELD<T,INTERLACING_TAG>::setRow( int i, T* value) throw (MEDEXCEPTION)
2513 const char * LOC = "FIELD<T,INTERLACING_TAG>::setRow(int i, T* value) : ";
2515 // JE (NB) NE SUIS PAS SUR DE CA ????
2517 valIndex = _support->getValIndFromGlobalNumber(i);
2519 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
2521 if ( getGaussPresence() )
2522 return dynamic_cast<ArrayGauss *>(_value)->setRow(valIndex, value) ;
2524 return dynamic_cast<ArrayNoGauss *>(_value)->setRow(valIndex, value) ;
2528 Update values array in the j^{th} column of FIELD values array with the given ones and
2529 according to specified mode.
2531 template <class T,class INTERLACING_TAG>
2532 inline void FIELD<T,INTERLACING_TAG>::setColumn( int i, T* value) throw (MEDEXCEPTION)
2534 if ( getGaussPresence() )
2535 return dynamic_cast<ArrayGauss *>(_value)->setColumn(i, value) ;
2537 return dynamic_cast<ArrayNoGauss *>(_value)->setColumn(i, value) ;
2541 Set the value of i^{th} element and j^{th} component with the given one.
2543 template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValueIJ(int i, int j, T value) throw (MEDEXCEPTION)
2545 const char * LOC = "FIELD<T,INTERLACING_TAG>::setValueIJ(int i, int j, T value) : ";
2548 valIndex = _support->getValIndFromGlobalNumber(i);
2550 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
2552 if ( getGaussPresence() )
2553 return dynamic_cast<ArrayGauss *>(_value)->setIJ(valIndex,j,value) ;
2555 return dynamic_cast<ArrayNoGauss *>(_value)->setIJ(valIndex,j,value) ;
2563 Fill values array with volume values.
2565 template <class T, class INTERLACING_TAG>
2566 void FIELD<T, INTERLACING_TAG>::getVolume() const throw (MEDEXCEPTION)
2568 const char * LOC = "FIELD<double>::getVolume() const : ";
2571 // The field has to be initilised by a non empty support and a
2572 // number of components = 1 and its value type has to be set to MED_REEL64
2573 // (ie a FIELD<double>)
2575 if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64))
2576 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to 1 and a value type set to MED_REEL64"));
2582 Fill values array with area values.
2584 template <class T, class INTERLACING_TAG>
2585 void FIELD<T, INTERLACING_TAG>::getArea() const throw (MEDEXCEPTION)
2587 const char * LOC = "FIELD<double>::getArea() const : ";
2590 // The field has to be initilised by a non empty support and a
2591 // number of components = 1 and its value type has to be set to MED_REEL64
2592 // (ie a FIELD<double>)
2594 if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64))
2595 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to 1 and a value type set to MED_REEL64"));
2601 Fill values array with length values.
2603 template <class T, class INTERLACING_TAG>
2604 void FIELD<T, INTERLACING_TAG>::getLength() const throw (MEDEXCEPTION)
2606 const char * LOC = "FIELD<double>::getLength() const : ";
2609 // The field has to be initilised by a non empty support and a
2610 // number of components = 1 and its value type has to be set to MED_REEL64
2611 // (ie a FIELD<double>)
2613 if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64))
2614 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to 1 and a value type set to MED_REEL64"));
2620 Fill values array with normal values.
2622 template <class T, class INTERLACING_TAG>
2623 void FIELD<T, INTERLACING_TAG>::getNormal() const throw (MEDEXCEPTION)
2625 const char * LOC = "FIELD<double>::getNormal() const : ";
2628 // The field has to be initilised by a non empty support and a
2629 // number of components = 1 and its value type has to be set to MED_REEL64
2630 // (ie a FIELD<double>)
2632 if (_support == (SUPPORT *) NULL)
2633 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64"));
2635 int dim_space = _support->getMesh()->getSpaceDimension();
2637 if ((_numberOfComponents != dim_space) || (_valueType != MED_EN::MED_REEL64))
2638 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64"));
2644 Fill values array with barycenter values.
2646 template <class T, class INTERLACING_TAG>
2647 void FIELD<T, INTERLACING_TAG>::getBarycenter() const throw (MEDEXCEPTION)
2649 const char * LOC = "FIELD<double>::getBarycenter() const : ";
2652 // The field has to be initilised by a non empty support and a number of
2653 //components = space dimension and its value type has to be set to MED_REEL64
2654 // (ie a FIELD<double>)
2656 if (_support == (SUPPORT *) NULL)
2657 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64"));
2659 int dim_space = _support->getMesh()->getSpaceDimension();
2661 if ((_numberOfComponents != dim_space) || (_valueType != MED_EN::MED_REEL64))
2662 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64"));
2668 Fill array by using T_Analytic.
2669 WARNING : "this" must have allocated its array by setting this->_support and this->_numberOfComponents properly.
2670 Typically you should use it on a field built with constructor FIELD<T>::FIELD<T>(SUPPORT *,int nbOfComponents)
2672 template <class T, class INTERLACING_TAG>
2673 void FIELD<T, INTERLACING_TAG>::fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION)
2675 const char * LOC = "void FIELD<T, INTERLACING_TAG>::fillFromAnalytic(myFuncType f) : ";
2677 if (_support == (SUPPORT *) NULL)
2678 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No Support defined."));
2680 MESH * mesh = _support->getMesh();
2681 int spaceDim = mesh->getSpaceDimension();
2682 const double * coord;
2684 const double * bary;
2685 FIELD<double,FullInterlace> * barycenterField=0;
2687 double ** xyz=new double* [spaceDim];
2688 bool deallocateXyz=false;
2689 if(_support->getEntity()==MED_EN::MED_NODE)
2691 if (_support->isOnAllElements())
2693 coord=mesh->getCoordinates(MED_EN::MED_NO_INTERLACE);
2694 for(i=0; i<spaceDim; i++)
2695 xyz[i]=(double *)coord+i*_numberOfValues;
2699 coord = mesh->getCoordinates(MED_EN::MED_FULL_INTERLACE);
2700 const int * nodesNumber=_support->getNumber(MED_EN::MED_ALL_ELEMENTS);
2701 for(i=0; i<spaceDim; i++)
2702 xyz[i]=new double[_numberOfValues];
2704 for(i=0;i<_numberOfValues;i++)
2706 for(j=0;j<spaceDim;j++)
2707 xyz[j][i]=coord[(nodesNumber[i]-1)*spaceDim+j];
2713 barycenterField = mesh->getBarycenter(_support);
2714 bary=barycenterField->getValue();
2715 for(i=0; i<spaceDim; i++)
2716 xyz[i]=(double *)(bary+i*_numberOfValues);
2718 T* valsToSet=(T*)getValue();
2719 double *temp=new double[spaceDim];
2720 for(i=0;i<_numberOfValues;i++)
2722 for(j=0;j<spaceDim;j++)
2724 f(temp,valsToSet+i*_numberOfComponents);
2728 delete barycenterField;
2730 for(j=0;j<spaceDim;j++)
2735 }//End namespace MEDMEM
2737 #endif /* FIELD_HXX */