13 #include "utilities.h"
14 #include "MEDMEM_Exception.hxx"
15 #include "MEDMEM_define.hxx"
17 #include "MEDMEM_Support.hxx"
18 #include "MEDMEM_Unit.hxx"
19 #include "MEDMEM_Array.hxx"
20 #include "MEDMEM_GenDriver.hxx"
22 #include "MEDMEM_MedFieldDriver.hxx"
23 #include "MEDMEM_MedMedDriver.hxx"
25 #include "MEDMEM_VtkFieldDriver.hxx"
26 #include "MEDMEM_VtkMedDriver.hxx"
28 using namespace MED_EN;
32 This class contains all the informations related with a template class FIELD :
33 - Components descriptions
34 - Time step description
35 - Location of the values (a SUPPORT class)
40 class FIELD_ // GENERIC POINTER TO a template <class T> class FIELD
60 Pointer to the support the field deals with.
63 const SUPPORT * _support ;
67 Number of field's components.
70 int _numberOfComponents ;
73 Number of field's values.
80 Array of size _numberOfComponents. /n
81 (constant, scalar, vector, tensor)/n
82 We could use an array of integer to store
85 - space dimension for vector,/n
86 - space dimension square for tensor./n
87 So numbers of values per entities would be
88 sum of _componentsTypes array.
90 Not implemented yet! All type are scalar !
93 int * _componentsTypes ;
96 Array of size _numberOfComponents
97 storing components names if any.
100 string * _componentsNames;
103 Array of size _numberOfComponents
104 storing components descriptions if any.
107 string * _componentsDescriptions;
110 Array of size _numberOfComponents
111 storing components units if any.
114 UNIT * _componentsUnits;
117 Array of size _numberOfComponents
118 storing components units if any.
121 string * _MEDComponentsUnits;
122 int _iterationNumber ;
126 // _valueType should be a static const. Here is an initialization exemple
127 // template < classType T > struct SET_VALUE_TYPE { static const med_type_champ _valueType = 0; }
128 // template < > struct SET_VALUE_TYPE<double> { static const med_type_champ _valueType = MED_EN::MED_REEL64; }
129 // template < > struct SET_VALUE_TYPE<int> { static const med_type_champ _valueType = MED_EN::MED_INT32; }
130 // static const med_type_champ _valueType = SET_VALUE_TYPE <T>::_valueType;
131 med_type_champ _valueType ;
133 vector<GENDRIVER *> _drivers; // Storage of the drivers currently in use
134 static void _checkFieldCompatibility(const FIELD_& m, const FIELD_& n ) throw (MEDEXCEPTION);
135 void _checkNormCompatibility(const FIELD<double>* p_field_volume=NULL) const throw (MEDEXCEPTION);
136 FIELD<double>* _getFieldSize() const;
140 friend class MED_MED_RDONLY_DRIVER;
141 friend class MED_MED_WRONLY_DRIVER;
142 friend class MED_MED_RDWR_DRIVER;
144 friend class VTK_MED_DRIVER;
153 FIELD_(const SUPPORT * Support, const int NumberOfComponents);
157 FIELD_(const FIELD_ &m);
164 // virtual void setIterationNumber (int IterationNumber);
165 // virtual void setOrderNumber (int OrderNumber);
166 // virtual void setFieldName (string& fieldName);
168 virtual void rmDriver(int index);
169 virtual int addDriver(driverTypes driverType,
170 const string & fileName="Default File Name.med",
171 const string & driverFieldName="Default Field Nam") ;
172 virtual int addDriver( GENDRIVER & driver);
173 virtual void read (const GENDRIVER &);
174 virtual void read(int index=0);
175 virtual void openAppend( void );
176 virtual void write(const GENDRIVER &);
177 virtual void write(int index=0, const string & driverName="");
179 virtual void writeAppend(const GENDRIVER &);
180 virtual void writeAppend(int index=0, const string & driverName="");
182 inline void setName(const string Name);
183 inline string getName() const;
184 inline void setDescription(const string Description);
185 inline string getDescription() const;
186 inline const SUPPORT * getSupport() const;
187 inline void setSupport(const SUPPORT * support);
188 inline void setNumberOfComponents(const int NumberOfComponents);
189 inline int getNumberOfComponents() const;
190 inline void setNumberOfValues(const int NumberOfValues);
191 inline int getNumberOfValues() const;
192 // inline void setComponentType(int *ComponentType);
193 // inline int * getComponentType() const;
194 // inline int getComponentTypeI(int i) const;
195 inline void setComponentsNames(const string * ComponentsNames);
196 inline void setComponentName(int i, const string ComponentName);
197 inline const string * getComponentsNames() const;
198 inline string getComponentName(int i) const;
199 inline void setComponentsDescriptions(const string * ComponentsDescriptions);
200 inline void setComponentDescription(int i, const string ComponentDescription);
201 inline const string * getComponentsDescriptions() const;
202 inline string getComponentDescription(int i) const;
204 // provisoire : en attendant de regler le probleme des unites !
205 inline void setComponentsUnits(const UNIT * ComponentsUnits);
206 inline const UNIT * getComponentsUnits() const;
207 inline const UNIT * getComponentUnit(int i) const;
208 inline void setMEDComponentsUnits(const string * MEDComponentsUnits);
209 inline void setMEDComponentUnit(int i, const string MEDComponentUnit);
210 inline const string * getMEDComponentsUnits() const;
211 inline string getMEDComponentUnit(int i) const;
213 inline void setIterationNumber(int IterationNumber);
214 inline int getIterationNumber() const;
215 inline void setTime(double Time);
216 inline double getTime() const;
217 inline void setOrderNumber(int OrderNumber);
218 inline int getOrderNumber() const;
220 inline void setValueType (const med_type_champ ValueType) ;
221 inline med_type_champ getValueType () const;
226 // ---------------------------------
227 // Implemented Methods : constructor
228 // ---------------------------------
229 using namespace MEDMEM;
237 inline void FIELD_::setName(const string Name)
244 inline string FIELD_::getName() const
249 Set FIELD description.
251 inline void FIELD_::setDescription(const string Description)
253 _description=Description;
256 Get FIELD description.
258 inline string FIELD_::getDescription() const
263 Set FIELD number of components.
265 inline void FIELD_::setNumberOfComponents(int NumberOfComponents)
267 _numberOfComponents=NumberOfComponents;
270 Get FIELD number of components.
272 inline int FIELD_::getNumberOfComponents() const
274 return _numberOfComponents ;
277 Set FIELD number of values.
279 It must be the same than in the associated SUPPORT object.
281 inline void FIELD_::setNumberOfValues(int NumberOfValues)
283 _numberOfValues=NumberOfValues;
286 Get FIELD number of value.
288 inline int FIELD_::getNumberOfValues() const
290 return _numberOfValues ;
293 // inline void FIELD_::setComponentType(int *ComponentType)
295 // _componentsTypes=ComponentType ;
297 // inline int * FIELD_::getComponentType() const
299 // return _componentsTypes ;
301 // inline int FIELD_::getComponentTypeI(int i) const
303 // return _componentsTypes[i-1] ;
307 Set FIELD components names.
309 Duplicate the ComponentsNames string array to put components names in
310 FIELD. ComponentsNames size must be equal to number of components.
312 inline void FIELD_::setComponentsNames(const string * ComponentsNames)
314 if (NULL == _componentsNames)
315 _componentsNames = new string[_numberOfComponents] ;
316 for (int i=0; i<_numberOfComponents; i++)
317 _componentsNames[i]=ComponentsNames[i] ;
320 Set FIELD i^th component name.
322 i must be >=1 and <= number of components.
324 inline void FIELD_::setComponentName(int i, const string ComponentName)
326 _componentsNames[i-1]=ComponentName ;
329 Get a reference to the string array which contain the components names.
331 This Array size is equal to number of components
333 inline const string * FIELD_::getComponentsNames() const
335 return _componentsNames ;
338 Get the name of the i^th component.
340 inline string FIELD_::getComponentName(int i) const
342 return _componentsNames[i-1] ;
345 Set FIELD components descriptions.
347 Duplicate the ComponentsDescriptions string array to put components
348 descriptions in FIELD.
349 ComponentsDescriptions size must be equal to number of components.
351 inline void FIELD_::setComponentsDescriptions(const string * ComponentsDescriptions)
353 if (NULL == _componentsDescriptions)
354 _componentsDescriptions = new string[_numberOfComponents] ;
355 for (int i=0; i<_numberOfComponents; i++)
356 _componentsDescriptions[i]=ComponentsDescriptions[i] ;
359 Set FIELD i^th component description.
361 i must be >=1 and <= number of components.
363 inline void FIELD_::setComponentDescription(int i,const string ComponentDescription)
365 _componentsDescriptions[i-1]=ComponentDescription ;
368 Get a reference to the string array which contain the components descriptions.
370 This Array size is equal to number of components
372 inline const string * FIELD_::getComponentsDescriptions() const
374 return _componentsDescriptions ;
377 Get the description of the i^th component.
379 inline string FIELD_::getComponentDescription(int i) const
381 return _componentsDescriptions[i-1];
386 Set FIELD components UNIT.
388 Duplicate the ComponentsUnits UNIT array to put components
390 ComponentsUnits size must be equal to number of components.
392 inline void FIELD_::setComponentsUnits(const UNIT * ComponentsUnits)
394 if (NULL == _componentsUnits)
395 _componentsUnits = new UNIT[_numberOfComponents] ;
396 for (int i=0; i<_numberOfComponents; i++)
397 _componentsUnits[i]=ComponentsUnits[i] ;
400 Get a reference to the UNIT array which contain the components units.
402 This Array size is equal to number of components
404 inline const UNIT * FIELD_::getComponentsUnits() const
406 return _componentsUnits ;
409 Get the UNIT of the i^th component.
411 inline const UNIT * FIELD_::getComponentUnit(int i) const
413 return &_componentsUnits[i-1] ;
416 Set FIELD components unit.
418 Duplicate the MEDComponentsUnits string array to put components
420 MEDComponentsUnits size must be equal to number of components.
423 inline void FIELD_::setMEDComponentsUnits(const string * MEDComponentsUnits)
425 if (NULL == _MEDComponentsUnits)
426 _MEDComponentsUnits = new string[_numberOfComponents] ;
427 for (int i=0; i<_numberOfComponents; i++)
428 _MEDComponentsUnits[i]=MEDComponentsUnits[i] ;
431 Set FIELD i^th component unit.
433 i must be >=1 and <= number of components.
435 inline void FIELD_::setMEDComponentUnit(int i, const string MEDComponentUnit)
437 _MEDComponentsUnits[i-1]=MEDComponentUnit ;
440 Get a reference to the string array which contain the components units.
442 This Array size is equal to number of components
444 inline const string * FIELD_::getMEDComponentsUnits() const
446 return _MEDComponentsUnits ;
449 Get the string for unit of the i^th component.
451 inline string FIELD_::getMEDComponentUnit(int i) const
453 return _MEDComponentsUnits[i-1] ;
456 Set the iteration number where FIELD has been calculated.
458 inline void FIELD_::setIterationNumber(int IterationNumber)
460 _iterationNumber=IterationNumber;
463 Get the iteration number where FIELD has been calculated.
465 inline int FIELD_::getIterationNumber() const
467 return _iterationNumber ;
470 Set the time (in second) where FIELD has been calculated.
472 inline void FIELD_::setTime(double Time)
477 Get the time (in second) where FIELD has been calculated.
479 inline double FIELD_::getTime() const
484 Set the order number where FIELD has been calculated.
486 It corresponds to internal iteration during one time step.
488 inline void FIELD_::setOrderNumber(int OrderNumber)
490 _orderNumber=OrderNumber ;
493 Get the order number where FIELD has been calculated.
495 inline int FIELD_::getOrderNumber() const
497 return _orderNumber ;
500 Get a reference to the SUPPORT object associated to FIELD.
502 inline const SUPPORT * FIELD_::getSupport() const
507 Set the reference to the SUPPORT object associated to FIELD.
509 Reference is not duplicate, so it must not be deleted.
511 inline void FIELD_::setSupport(const SUPPORT * support)
516 Get the FIELD med value type (MED_INT32 or MED_REEL64).
518 inline med_type_champ FIELD_::getValueType () const
523 Set the FIELD med value type (MED_INT32 or MED_REEL64).
525 inline void FIELD_::setValueType (const med_type_champ ValueType)
527 _valueType = ValueType ;
530 /////////////////////////
531 // END OF CLASS FIELD_ //
532 /////////////////////////
536 This template class contains informations related with a FIELD :
537 - Values of the field
542 template <class T> class FIELD : public FIELD_
545 // ------- Drivers Management Part
548 //-----------------------//
550 //-----------------------//
553 virtual GENDRIVER * run(const string & fileName, FIELD<T> * ptrFIELD) const = 0 ;
556 //-------------------------------------------------------//
557 template <class T2> class INSTANCE_DE : public INSTANCE
558 //-------------------------------------------------------//
561 GENDRIVER * run(const string & fileName, FIELD<T> * ptrFIELD) const
563 return new T2(fileName,ptrFIELD);
567 // static INSTANCE_DE<MED_FIELD_RDONLY_DRIVER> inst_med_rdonly ;
568 static INSTANCE_DE<MED_FIELD_RDWR_DRIVER<T> > inst_med ;
569 static INSTANCE_DE<VTK_FIELD_DRIVER<T> > inst_vtk ;
571 static const INSTANCE * const instances[] ;
573 // ------ End of Drivers Management Part
575 // array of value of type T
576 MEDARRAY<T> *_value ;
579 void _operation(const FIELD& m,const FIELD& n, const medModeSwitch mode, char* Op);
580 void _operationInitialize(const FIELD& m,const FIELD& n, char* Op);
581 void _add_in_place(const FIELD& m,const FIELD& n, const medModeSwitch mode);
582 void _sub_in_place(const FIELD& m,const FIELD& n, const medModeSwitch mode);
583 void _mul_in_place(const FIELD& m,const FIELD& n, const medModeSwitch mode);
584 void _div_in_place(const FIELD& m,const FIELD& n, const medModeSwitch mode);
589 FIELD(const FIELD &m);
590 FIELD & operator=(const FIELD &m); // A FAIRE
591 FIELD(const SUPPORT * Support, const int NumberOfComponents, const medModeSwitch Mode=MED_FULL_INTERLACE) throw (MEDEXCEPTION) ; // Ajout NB Constructeur FIELD avec allocation de memoire de tous ses attribut
592 FIELD(const SUPPORT * Support, driverTypes driverType,
593 const string & fileName="", const string & fieldName="",
594 const int iterationNumber = -1, const int orderNumber = -1)
595 throw (MEDEXCEPTION);
598 const FIELD operator+(const FIELD& m) const;
599 const FIELD operator-(const FIELD& m) const;
600 const FIELD operator*(const FIELD& m) const;
601 const FIELD operator/(const FIELD& m) const;
602 const FIELD operator-() const;
603 FIELD& operator+=(const FIELD& m);
604 FIELD& operator-=(const FIELD& m);
605 FIELD& operator*=(const FIELD& m);
606 FIELD& operator/=(const FIELD& m);
607 static FIELD* add(const FIELD& m, const FIELD& n);
608 static FIELD* sub(const FIELD& m, const FIELD& n);
609 static FIELD* mul(const FIELD& m, const FIELD& n);
610 static FIELD* div(const FIELD& m, const FIELD& n);
611 double normMax() const throw (MEDEXCEPTION);
612 double norm2() const throw (MEDEXCEPTION);
613 void applyLin(T a, T b);
614 template <T T_function(T)> void applyFunc();
615 static FIELD* scalarProduct(const FIELD& m, const FIELD& n);
616 double normL2(int component, const FIELD<double> * p_field_volume=NULL) const;
617 double normL2(const FIELD<double> * p_field_volume=NULL) const;
618 double normL1(int component, const FIELD<double> * p_field_volume=NULL) const;
619 double normL1(const FIELD<double> * p_field_volume=NULL) const;
621 friend class MED_FIELD_RDONLY_DRIVER<T>;
622 friend class MED_FIELD_WRONLY_DRIVER<T>;
624 friend class VTK_FIELD_DRIVER<T>;
625 //friend class MED_FIELD_RDWR_DRIVER <T>;
628 void rmDriver(int index=0);
629 int addDriver(driverTypes driverType,
630 const string & fileName="Default File Name.med",
631 const string & driverFieldName="Default Field Name") ;
632 int addDriver(GENDRIVER & driver);
634 void allocValue(const int NumberOfComponents);
635 void allocValue(const int NumberOfComponents, const int LengthValue);
639 inline void read(int index=0);
640 inline void read(const GENDRIVER & genDriver);
641 inline void write(int index=0, const string & driverName = "");
642 inline void write(const GENDRIVER &);
644 inline void writeAppend(int index=0, const string & driverName = "");
645 inline void writeAppend(const GENDRIVER &);
647 inline void setValue(MEDARRAY<T> *Value);
649 inline MEDARRAY<T>* getvalue() const;
650 inline const T* getValue(medModeSwitch Mode) const;
651 inline const T* getValueI(medModeSwitch Mode,int i) const;
652 inline T getValueIJ(int i,int j) const;
654 inline void setValue(medModeSwitch mode, T* value);
655 inline void setValueI(medModeSwitch mode, int i, T* value);
656 inline void setValueIJ(int i, int j, T value);
659 This fonction feeds the FIELD<double> private attributs _value with the
660 volume of each cells belonging to the argument Support. The field has to be
661 initialised via the constructor FIELD<double>(const SUPPORT * , const int )
662 with Support as SUPPORT argument, 1 has the number of components, and Support
663 has be a SUPPORT on 3D cells. This initialisation could be done by the empty
664 constructor followed by a setSupport and setNumberOfComponents call but it has
665 be followed by a setValueType(MED_REEL64) call.
667 void getVolume() const throw (MEDEXCEPTION) ;
669 This fonction feeds the FIELD<double> private attributs _value with the
670 area of each cells (or faces) belonging to the attribut _support. The field
671 has to be initialised via the constructor FIELD<double>(const SUPPORT * ,
672 const int ) with 1 has the number of components, and _support has be a
673 SUPPORT on 2D cells or 3D faces. This initialisation could be done by the
674 empty constructor followed by a setSupport and setNumberOfComponents call but
675 it has be followed by a setValueType(MED_REEL64) call.
677 void getArea() const throw (MEDEXCEPTION) ;
679 This fonction feeds the FIELD<double> private attributs _value with the
680 length of each segments belonging to the attribut _support. The field has
681 to be initialised via the constructor FIELD<double>(const SUPPORT * ,
682 const int ) with 1 has the number of components, and _support has be a
683 SUPPORT on 3D edges or 2D faces. This initialisation could be done by the
684 empty constructor followed by a setSupport and setNumberOfComponents call but
685 it has be followed by a setValueType(MED_REEL64) call.
687 void getLength() const throw (MEDEXCEPTION) ;
689 This fonction feeds the FIELD<double> private attributs _value with the
690 normal vector of each faces belonging to the attribut _support. The field
691 has to be initialised via the constructor FIELD<double>(const SUPPORT * ,
692 const int ) with the space dimension has the number of components, and
693 _support has be a SUPPORT on 3D or 2D faces. This initialisation could be done
694 by the empty constructor followed by a setSupport and setNumberOfComponents
695 call but it has be followed by a setValueType(MED_REEL64) call.
697 void getNormal() const throw (MEDEXCEPTION) ;
699 This fonction feeds the FIELD<double> private attributs _value with the
700 barycenter of each faces or cells or edges belonging to the attribut _support.
701 The field has to be initialised via the constructor
702 FIELD<double>(const SUPPORT * ,const int ) with the space dimension has the
703 number of components, and _support has be a SUPPORT on 3D cells or 2D faces.
704 This initialisation could be done by the empty constructor followed by a
705 setSupport and setNumberOfComponents call but it has be followed by a
706 setValueType(MED_REEL64) call.
708 void getBarycenter() const throw (MEDEXCEPTION) ;
712 // --------------------
713 // Implemented Methods
714 // --------------------
715 using namespace MEDMEM;
718 Constructor with no parameter, most of the attribut members are set to NULL.
720 template <class T> FIELD<T>::FIELD():
721 _value((MEDARRAY<T>*)NULL)
723 MESSAGE("Constructeur FIELD sans parametre");
727 Constructor with parameters such that all attrribut are set but the _value
728 attribut is allocated but not set.
730 template <class T> FIELD<T>::FIELD(const SUPPORT * Support,
731 const int NumberOfComponents, const medModeSwitch Mode) throw (MEDEXCEPTION) :
732 FIELD_(Support, NumberOfComponents)
734 BEGIN_OF("FIELD<T>::FIELD(const SUPPORT * Support, const int NumberOfComponents, const medModeSwitch Mode)");
738 _numberOfValues = Support->getNumberOfElements(MED_ALL_ELEMENTS);
740 catch (MEDEXCEPTION &ex) {
741 MESSAGE("No value defined ! ("<<ex.what()<<")");
742 _value = (MEDARRAY<T>*)NULL ;
744 MESSAGE("FIELD : constructeur : "<< _numberOfValues <<" et "<< NumberOfComponents);
745 if (0<_numberOfValues) {
746 _value = new MEDARRAY<T>(_numberOfComponents,_numberOfValues,Mode);
749 _value = (MEDARRAY<T>*)NULL ;
751 END_OF("FIELD<T>::FIELD(const SUPPORT * Support, const int NumberOfComponents, const medModeSwitch Mode)");
758 template <class T> void FIELD<T>::init ()
765 template <class T> FIELD<T>::FIELD(const FIELD & m):
768 MESSAGE("Constructeur FIELD de recopie");
769 if (m._value != NULL)
771 // copie only default !
772 _value = new MEDARRAY<T>(* m._value,false);
775 _value = (MEDARRAY<T> *) NULL;
776 //_drivers = m._drivers;
782 template <class T> FIELD<T> & FIELD<T>::operator=(const FIELD &m)
784 MESSAGE("Appel de FIELD<T>::operator=");
788 Overload addition operator.
789 This operation is authorized only for compatible fields that have the same support.
790 The compatibility checking includes equality tests of the folowing data members:/n
792 - _numberOfComponents
795 - _MEDComponentsUnits.
797 The data members of the returned field are initialized, based on the first field, except for the name,
798 which is the combination of the two field's names and the operator.
799 Advised Utilisation in C++ : <tt> FIELD<T> c = a + b; </tt> /n
800 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
801 When using python, this operator calls the copy constructor in any case.
802 The user has to be aware that when using operator + in associatives expressions like
803 <tt> a = b + c + d +e; </tt> /n
804 no optimisation is performed : the evaluation of last expression requires the construction of
808 const FIELD<T> FIELD<T>::operator+(const FIELD & m) const
810 BEGIN_OF("FIELD<T>::operator+(const FIELD & m)");
811 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
813 // Select mode : avoid if possible any calculation of other mode for fields m or *this
815 if(this->getvalue()->getMode()==m.getvalue()->getMode() || this->getvalue()->isOtherCalculated())
816 mode=m.getvalue()->getMode();
818 mode=this->getvalue()->getMode();
820 // Creation of the result - memory is allocated by FIELD constructor
821 FIELD<T> result(this->getSupport(),this->getNumberOfComponents(),mode);
822 //result._operation(*this,m,mode,"+"); // perform Atribute's initialization & addition
823 result._operationInitialize(*this,m,"+"); // perform Atribute's initialization
824 result._add_in_place(*this,m,mode); // perform addition
826 END_OF("FIELD<T>::operator+(const FIELD & m)");
830 /*! Overloaded Operator +=
831 * Operations are directly performed in the first field's array.
832 * This operation is authorized only for compatible fields that have the same support.
835 FIELD<T>& FIELD<T>::operator+=(const FIELD & m)
837 BEGIN_OF("FIELD<T>::operator+=(const FIELD & m)");
838 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
840 // We choose to keep *this mode, even if it may cost a re-calculation for m
841 medModeSwitch mode=this->getvalue()->getMode();
842 const T* value1=m.getValue(mode); // get pointers to the values we are adding
844 // get a non const pointer to the inside array of values and perform operation
845 T * value=const_cast<T *> (getValue(mode));
846 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
847 const T* endV=value+size; // pointer to the end of value
848 for(;value!=endV; value1++,value++)
850 // if it exists, the alternate mode needs to be cleared because it is not up-to-date anymore
851 this->getvalue()->clearOtherMode();
852 END_OF("FIELD<T>::operator+=(const FIELD & m)");
857 /*! Addition of fields. Static member function.
858 * The function return a pointer to a new created field that holds the addition.
859 * Data members are checked for compatibility and initialized.
860 * The user is in charge of memory deallocation.
863 FIELD<T>* FIELD<T>::add(const FIELD& m, const FIELD& n)
865 BEGIN_OF("FIELD<T>::add(const FIELD & m, const FIELD& n)");
866 FIELD_::_checkFieldCompatibility(m, n); // may throw exception
868 // Select mode : avoid if possible any calculation of other mode for fields m or *this
870 if(m.getvalue()->getMode()==n.getvalue()->getMode() || n.getvalue()->isOtherCalculated())
871 mode=m.getvalue()->getMode();
873 mode=n.getvalue()->getMode();
875 // Creation of a new field
876 FIELD<T>* result = new FIELD<T>(m.getSupport(),m.getNumberOfComponents(),mode);
877 result->_operationInitialize(m,n,"+"); // perform Atribute's initialization
878 result->_add_in_place(m,n,mode); // perform addition
880 END_OF("FIELD<T>::add(const FIELD & m, const FIELD& n)");
885 Overload substraction operator.
886 This operation is authorized only for compatible fields that have the same support.
887 The compatibility checking includes equality tests of the folowing data members:/n
889 - _numberOfComponents
892 - _MEDComponentsUnits.
894 The data members of the returned field are initialized, based on the first field, except for the name,
895 which is the combination of the two field's names and the operator.
896 Advised Utilisation in C++ : <tt> FIELD<T> c = a - b; </tt> /n
897 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
898 When using python, this operator calls the copy constructor in any case.
899 The user has to be aware that when using operator - in associatives expressions like
900 <tt> a = b - c - d -e; </tt> /n
901 no optimisation is performed : the evaluation of last expression requires the construction of
905 const FIELD<T> FIELD<T>::operator-(const FIELD & m) const
907 BEGIN_OF("FIELD<T>::operator-(const FIELD & m)");
908 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
910 // Select mode : avoid if possible any calculation of other mode for fields m or *this
912 if(this->getvalue()->getMode()==m.getvalue()->getMode() || this->getvalue()->isOtherCalculated())
913 mode=m.getvalue()->getMode();
915 mode=this->getvalue()->getMode();
917 // Creation of the result - memory is allocated by FIELD constructor
918 FIELD<T> result(this->getSupport(),this->getNumberOfComponents(),mode);
919 //result._operation(*this,m,mode,"-"); // perform Atribute's initialization & substraction
920 result._operationInitialize(*this,m,"-"); // perform Atribute's initialization
921 result._sub_in_place(*this,m,mode); // perform substracion
923 END_OF("FIELD<T>::operator-(const FIELD & m)");
928 const FIELD<T> FIELD<T>::operator-() const
930 BEGIN_OF("FIELD<T>::operator-()");
932 medModeSwitch mode=this->getvalue()->getMode();
933 // Creation of the result - memory is allocated by FIELD constructor
934 FIELD<T> result(this->getSupport(),this->getNumberOfComponents(),mode);
935 // Atribute's initialization
936 result.setName("- "+getName());
937 result.setComponentsNames(getComponentsNames());
938 // not yet implemented setComponentType(getComponentType());
939 result.setComponentsDescriptions(getComponentsDescriptions());
940 result.setMEDComponentsUnits(getMEDComponentsUnits());
941 result.setComponentsUnits(getComponentsUnits());
942 result.setIterationNumber(getIterationNumber());
943 result.setTime(getTime());
944 result.setOrderNumber(getOrderNumber());
945 result.setValueType(getValueType());
947 const T* value1=getValue(mode);
948 // get a non const pointer to the inside array of values and perform operation
949 T * value=const_cast<T *> (result.getValue(mode));
950 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
951 const T* endV=value+size; // pointer to the end of value
953 for(;value!=endV; value1++,value++)
955 END_OF("FIELD<T>::operator-=(const FIELD & m)");
959 /*! Overloaded Operator -=
960 * Operations are directly performed in the first field's array.
961 * This operation is authorized only for compatible fields that have the same support.
964 FIELD<T>& FIELD<T>::operator-=(const FIELD & m)
966 BEGIN_OF("FIELD<T>::operator-=(const FIELD & m)");
967 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
969 // We choose to keep *this mode, even if it may cost a re-calculation for m
970 medModeSwitch mode=this->getvalue()->getMode();
971 const T* value1=m.getValue(mode); // get pointers to the values we are adding
973 // get a non const pointer to the inside array of values and perform operation
974 T * value=const_cast<T *> (getValue(mode));
975 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
976 const T* endV=value+size; // pointer to the end of value
978 for(;value!=endV; value1++,value++)
980 // if it exists, the alternate mode needs to be cleared because it is not up-to-date anymore
981 this->getvalue()->clearOtherMode();
982 END_OF("FIELD<T>::operator-=(const FIELD & m)");
987 /*! Substraction of fields. Static member function.
988 * The function return a pointer to a new created field that holds the substraction.
989 * Data members are checked for compatibility and initialized.
990 * The user is in charge of memory deallocation.
993 FIELD<T>* FIELD<T>::sub(const FIELD& m, const FIELD& n)
995 BEGIN_OF("FIELD<T>::sub(const FIELD & m, const FIELD& n)");
996 FIELD_::_checkFieldCompatibility(m, n); // may throw exception
998 // Select mode : avoid if possible any calculation of other mode for fields m or *this
1000 if(m.getvalue()->getMode()==n.getvalue()->getMode() || n.getvalue()->isOtherCalculated())
1001 mode=m.getvalue()->getMode();
1003 mode=n.getvalue()->getMode();
1005 // Creation of a new field
1006 FIELD<T>* result = new FIELD<T>(m.getSupport(),m.getNumberOfComponents(),mode);
1007 result->_operationInitialize(m,n,"-"); // perform Atribute's initialization
1008 result->_sub_in_place(m,n,mode); // perform substraction
1010 END_OF("FIELD<T>::sub(const FIELD & m, const FIELD& n)");
1015 Overload multiplication operator.
1016 This operation is authorized only for compatible fields that have the same support.
1017 The compatibility checking includes equality tests of the folowing data members:/n
1019 - _numberOfComponents
1022 - _MEDComponentsUnits.
1024 The data members of the returned field are initialized, based on the first field, except for the name,
1025 which is the combination of the two field's names and the operator.
1026 Advised Utilisation in C++ : <tt> FIELD<T> c = a * b; </tt> /n
1027 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1028 When using python, this operator calls the copy constructor in any case.
1029 The user has to be aware that when using operator * in associatives expressions like
1030 <tt> a = b * c * d *e; </tt> /n
1031 no optimisation is performed : the evaluation of last expression requires the construction of
1035 const FIELD<T> FIELD<T>::operator*(const FIELD & m) const
1037 BEGIN_OF("FIELD<T>::operator*(const FIELD & m)");
1038 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1040 // Select mode : avoid if possible any calculation of other mode for fields m or *this
1042 if(this->getvalue()->getMode()==m.getvalue()->getMode() || this->getvalue()->isOtherCalculated())
1043 mode=m.getvalue()->getMode();
1045 mode=this->getvalue()->getMode();
1047 // Creation of the result - memory is allocated by FIELD constructor
1048 FIELD<T> result(this->getSupport(),this->getNumberOfComponents(),mode);
1049 //result._operation(*this,m,mode,"*"); // perform Atribute's initialization & multiplication
1050 result._operationInitialize(*this,m,"*"); // perform Atribute's initialization
1051 result._mul_in_place(*this,m,mode); // perform multiplication
1053 END_OF("FIELD<T>::operator*(const FIELD & m)");
1057 /*! Overloaded Operator *=
1058 * Operations are directly performed in the first field's array.
1059 * This operation is authorized only for compatible fields that have the same support.
1062 FIELD<T>& FIELD<T>::operator*=(const FIELD & m)
1064 BEGIN_OF("FIELD<T>::operator*=(const FIELD & m)");
1065 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1067 // We choose to keep *this mode, even if it may cost a re-calculation for m
1068 medModeSwitch mode=this->getvalue()->getMode();
1069 const T* value1=m.getValue(mode); // get pointers to the values we are adding
1071 // get a non const pointer to the inside array of values and perform operation
1072 T * value=const_cast<T *> (getValue(mode));
1073 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1074 const T* endV=value+size; // pointer to the end of value
1076 for(;value!=endV; value1++,value++)
1078 // if it exists, the alternate mode needs to be cleared because it is not up-to-date anymore
1079 this->getvalue()->clearOtherMode();
1080 END_OF("FIELD<T>::operator*=(const FIELD & m)");
1085 /*! Multiplication of fields. Static member function.
1086 * The function return a pointer to a new created field that holds the multiplication.
1087 * Data members are checked for compatibility and initialized.
1088 * The user is in charge of memory deallocation.
1091 FIELD<T>* FIELD<T>::mul(const FIELD& m, const FIELD& n)
1093 BEGIN_OF("FIELD<T>::mul(const FIELD & m, const FIELD& n)");
1094 FIELD_::_checkFieldCompatibility(m, n); // may throw exception
1096 // Select mode : avoid if possible any calculation of other mode for fields m or *this
1098 if(m.getvalue()->getMode()==n.getvalue()->getMode() || n.getvalue()->isOtherCalculated())
1099 mode=m.getvalue()->getMode();
1101 mode=n.getvalue()->getMode();
1103 // Creation of a new field
1104 FIELD<T>* result = new FIELD<T>(m.getSupport(),m.getNumberOfComponents(),mode);
1105 result->_operationInitialize(m,n,"*"); // perform Atribute's initialization
1106 result->_mul_in_place(m,n,mode); // perform multiplication
1108 END_OF("FIELD<T>::mul(const FIELD & m, const FIELD& n)");
1114 Overload division operator.
1115 This operation is authorized only for compatible fields that have the same support.
1116 The compatibility checking includes equality tests of the folowing data members:/n
1118 - _numberOfComponents
1121 - _MEDComponentsUnits.
1123 The data members of the returned field are initialized, based on the first field, except for the name,
1124 which is the combination of the two field's names and the operator.
1125 Advised Utilisation in C++ : <tt> FIELD<T> c = a / b; </tt> /n
1126 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1127 When using python, this operator calls the copy constructor in any case.
1128 The user has to be aware that when using operator / in associatives expressions like
1129 <tt> a = b / c / d /e; </tt> /n
1130 no optimisation is performed : the evaluation of last expression requires the construction of
1134 const FIELD<T> FIELD<T>::operator/(const FIELD & m) const
1136 BEGIN_OF("FIELD<T>::operator/(const FIELD & m)");
1137 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1139 // Select mode : avoid if possible any calculation of other mode for fields m or *this
1141 if(this->getvalue()->getMode()==m.getvalue()->getMode() || this->getvalue()->isOtherCalculated())
1142 mode=m.getvalue()->getMode();
1144 mode=this->getvalue()->getMode();
1146 // Creation of the result - memory is allocated by FIELD constructor
1147 FIELD<T> result(this->getSupport(),this->getNumberOfComponents(),mode);
1148 //result._operation(*this,m,mode,"/"); // perform Atribute's initialization & division
1149 result._operationInitialize(*this,m,"/"); // perform Atribute's initialization
1150 result._div_in_place(*this,m,mode); // perform division
1152 END_OF("FIELD<T>::operator/(const FIELD & m)");
1157 /*! Overloaded Operator /=
1158 * Operations are directly performed in the first field's array.
1159 * This operation is authorized only for compatible fields that have the same support.
1162 FIELD<T>& FIELD<T>::operator/=(const FIELD & m)
1164 BEGIN_OF("FIELD<T>::operator/=(const FIELD & m)");
1165 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1167 // We choose to keep *this mode, even if it may cost a re-calculation for m
1168 medModeSwitch mode=this->getvalue()->getMode();
1169 const T* value1=m.getValue(mode); // get pointers to the values we are adding
1171 // get a non const pointer to the inside array of values and perform operation
1172 T * value=const_cast<T *> (getValue(mode));
1173 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1174 const T* endV=value+size; // pointer to the end of value
1176 for(;value!=endV; value1++,value++)
1178 // if it exists, the alternate mode needs to be cleared because it is not up-to-date anymore
1179 this->getvalue()->clearOtherMode();
1180 END_OF("FIELD<T>::operator/=(const FIELD & m)");
1185 /*! Division of fields. Static member function.
1186 * The function return a pointer to a new created field that holds the division.
1187 * Data members are checked for compatibility and initialized.
1188 * The user is in charge of memory deallocation.
1191 FIELD<T>* FIELD<T>::div(const FIELD& m, const FIELD& n)
1193 BEGIN_OF("FIELD<T>::div(const FIELD & m, const FIELD& n)");
1194 FIELD_::_checkFieldCompatibility(m, n); // may throw exception
1196 // Select mode : avoid if possible any calculation of other mode for fields m or *this
1198 if(m.getvalue()->getMode()==n.getvalue()->getMode() || n.getvalue()->isOtherCalculated())
1199 mode=m.getvalue()->getMode();
1201 mode=n.getvalue()->getMode();
1203 // Creation of a new field
1204 FIELD<T>* result = new FIELD<T>(m.getSupport(),m.getNumberOfComponents(),mode);
1205 result->_operationInitialize(m,n,"/"); // perform Atribute's initialization
1206 result->_div_in_place(m,n,mode); // perform division
1208 END_OF("FIELD<T>::div(const FIELD & m, const FIELD& n)");
1215 This internal method initialize the members of a new field created to hold the result of the operation Op .
1216 Initialization is based on the first field, except for the name, which is the combination of the two field's names
1221 void FIELD<T>::_operationInitialize(const FIELD& m,const FIELD& n, char* Op)
1223 MESSAGE("Appel methode interne _add" << Op);
1225 // Atribute's initialization (copy of the first field's attributes)
1226 // Other data members (_support, _numberOfValues) are initialized in the field's constr.
1227 setName(m.getName()+" "+Op+" "+n.getName());
1228 setComponentsNames(m.getComponentsNames());
1229 // not yet implemented setComponentType(m.getComponentType());
1230 setComponentsDescriptions(m.getComponentsDescriptions());
1231 setMEDComponentsUnits(m.getMEDComponentsUnits());
1233 // The following data member may differ from field m to n.
1234 // The initialization is done based on the first field.
1235 setComponentsUnits(m.getComponentsUnits());
1236 setIterationNumber(m.getIterationNumber());
1237 setTime(m.getTime());
1238 setOrderNumber(m.getOrderNumber());
1239 setValueType(m.getValueType());
1245 Internal method called by FIELD<T>::operator+ and FIELD<T>::add to perform addition "in place".
1246 This method is applied to a just created field with medModeSwitch mode.
1247 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1252 void FIELD<T>::_add_in_place(const FIELD& m,const FIELD& n, const medModeSwitch mode)
1254 // get pointers to the values we are adding
1255 const T* value1=m.getValue(mode);
1256 const T* value2=n.getValue(mode);
1257 // get a non const pointer to the inside array of values and perform operation
1258 T * value=const_cast<T *> (getValue(mode));
1260 const int size=getNumberOfValues()*getNumberOfComponents();
1262 const T* endV1=value1+size;
1263 for(;value1!=endV1; value1++,value2++,value++)
1264 *value=(*value1)+(*value2);
1269 Internal method called by FIELD<T>::operator- and FIELD<T>::sub to perform substraction "in place".
1270 This method is applied to a just created field with medModeSwitch mode.
1271 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1276 void FIELD<T>::_sub_in_place(const FIELD& m,const FIELD& n, const medModeSwitch mode)
1278 // get pointers to the values we are adding
1279 const T* value1=m.getValue(mode);
1280 const T* value2=n.getValue(mode);
1281 // get a non const pointer to the inside array of values and perform operation
1282 T * value=const_cast<T *> (getValue(mode));
1284 const int size=getNumberOfValues()*getNumberOfComponents();
1286 const T* endV1=value1+size;
1287 for(;value1!=endV1; value1++,value2++,value++)
1288 *value=(*value1)-(*value2);
1293 Internal method called by FIELD<T>::operator* and FIELD<T>::mul to perform multiplication "in place".
1294 This method is applied to a just created field with medModeSwitch mode.
1295 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1300 void FIELD<T>::_mul_in_place(const FIELD& m,const FIELD& n, const medModeSwitch mode)
1302 // get pointers to the values we are adding
1303 const T* value1=m.getValue(mode);
1304 const T* value2=n.getValue(mode);
1305 // get a non const pointer to the inside array of values and perform operation
1306 T * value=const_cast<T *> (getValue(mode));
1308 const int size=getNumberOfValues()*getNumberOfComponents();
1310 const T* endV1=value1+size;
1311 for(;value1!=endV1; value1++,value2++,value++)
1312 *value=(*value1)*(*value2);
1317 Internal method called by FIELD<T>::operator/ and FIELD<T>::div to perform division "in place".
1318 This method is applied to a just created field with medModeSwitch mode.
1319 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1324 void FIELD<T>::_div_in_place(const FIELD& m,const FIELD& n, const medModeSwitch mode)
1326 // get pointers to the values we are adding
1327 const T* value1=m.getValue(mode);
1328 const T* value2=n.getValue(mode);
1329 // get a non const pointer to the inside array of values and perform operation
1330 T * value=const_cast<T *> (getValue(mode));
1332 const int size=getNumberOfValues()*getNumberOfComponents();
1334 const T* endV1=value1+size;
1335 for(;value1!=endV1; value1++,value2++,value++)
1336 *value=(*value1)/(*value2);
1341 template <class T> double FIELD<T>::normMax() const throw (MEDEXCEPTION)
1343 const T* value=getValue(getvalue()->getMode()); // get pointer to the values
1344 const int size=getNumberOfValues()*getNumberOfComponents();
1345 if (size <= 0) // Size of array has to be strictly positive
1348 diagnosis="FIELD<T>::normMax() : cannot compute the norm of "+getName()+
1349 " : it size is non positive!";
1350 throw MEDEXCEPTION(diagnosis.c_str());
1352 const T* lastvalue=value+size; // get pointer just after last value
1353 const T* pMax=value; // pointer to the max value
1354 const T* pMin=value; // pointer to the min value
1356 // get pointers to the max & min value of array
1357 while ( ++value != lastvalue )
1359 if ( *pMin > *value )
1361 if ( *pMax < *value )
1365 T Max= *pMax>(T) 0 ? *pMax : -*pMax; // Max=abs(*pMax)
1366 T Min= *pMin>(T) 0 ? *pMin : -*pMin; // Min=abs(*pMin)
1368 return Max>Min ? static_cast<double>(Max) : static_cast<double>(Min);
1371 /*! Return Euclidien norm
1373 template <class T> double FIELD<T>::norm2() const throw (MEDEXCEPTION)
1375 const T* value=this->getValue(this->getvalue()->getMode()); // get const pointer to the values
1376 const int size=getNumberOfValues()*getNumberOfComponents(); // get size of array
1377 if (size <= 0) // Size of array has to be strictly positive
1380 diagnosis="FIELD<T>::norm2() : cannot compute the norm of "+getName()+
1381 " : it size is non positive!";
1382 throw MEDEXCEPTION(diagnosis.c_str());
1384 const T* lastvalue=value+size; // point just after last value
1386 T result((T)0); // init
1387 for( ; value!=lastvalue ; ++value)
1388 result += (*value) * (*value);
1390 return std::sqrt(static_cast<double> (result));
1394 /*! Apply to each (scalar) field component the template parameter T_function,
1395 * which is a pointer to function.
1396 * Since the pointer is known at compile time, the function is inlined into the inner loop!
1397 * calculation is done "in place".
1400 * \code myField.applyFunc<std::sqrt>(); // apply sqare root function \endcode
1401 * \code myField.applyFunc<myFunction>(); // apply your own created function \endcode
1403 template <class T> template <T T_function(T)>
1404 void FIELD<T>::applyFunc()
1406 medModeSwitch mode=getvalue()->getMode();
1408 // get a non const pointer to the inside array of values and perform operation
1409 T * value=const_cast<T *> (getValue(mode));
1410 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1412 if (size>0) // for a negative size, there is nothing to do
1414 const T* lastvalue=value+size; // pointer to the end of value
1415 for(;value!=lastvalue; ++value) // apply linear transformation
1416 *value = T_function(*value);
1417 // if it exists, the alternate mode needs to be cleared because it is not up-to-date anymore
1418 getvalue()->clearOtherMode();
1423 /*! Apply to each (scalar) field component the linear function x -> ax+b.
1424 * calculation is done "in place".
1426 template <class T> void FIELD<T>::applyLin(T a, T b)
1428 medModeSwitch mode=getvalue()->getMode();
1430 // get a non const pointer to the inside array of values and perform operation in place
1431 T * value=const_cast<T *> (getValue(mode));
1432 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1434 if (size>0) // for a negative size, there is nothing to do
1436 const T* lastvalue=value+size; // pointer to the end of value
1437 for(;value!=lastvalue; ++value) // apply linear transformation
1438 *value = a*(*value)+b;
1439 // if it exists, the alternate mode needs to be cleared because it is not up-to-date anymore
1440 getvalue()->clearOtherMode();
1446 * Return a pointer to a new field that holds the scalar product. Static member function.
1447 * This operation is authorized only for compatible fields that have the same support.
1448 * The compatibility checking includes equality tests of the folowing data members:/n
1450 * - _numberOfComponents
1452 * - _componentsTypes
1453 * - _MEDComponentsUnits.
1454 * Data members are initialized.
1455 * The new field point to the same support and has one component.
1456 * Each value of it is the scalar product of the two argument's fields.
1457 * The user is in charge of memory deallocation.
1459 template <class T> FIELD<T>* FIELD<T>::scalarProduct(const FIELD & m, const FIELD & n)
1461 FIELD_::_checkFieldCompatibility( m, n); // may throw exception
1462 // we need a MED_FULL_INTERLACE representation of m & n to compute the scalar product
1463 const medModeSwitch mode=MED_FULL_INTERLACE;
1465 const int numberOfElements=m.getNumberOfValues(); // strictly positive
1466 const int NumberOfComponents=m.getNumberOfComponents(); // strictly positive
1468 // Creation & init of a the result field on the same suppot, with one component
1469 FIELD<T>* result = new FIELD<T>(m.getSupport(),1,mode);
1470 result->setName( "scalarProduct ( " + m.getName() + " , " + n.getName() + " )" );
1471 result->setIterationNumber(m.getIterationNumber());
1472 result->setTime(m.getTime());
1473 result->setOrderNumber(m.getOrderNumber());
1474 result->setValueType(m.getValueType());
1476 const T* value1=m.getValue(mode); // get const pointer to the values
1477 const T* value2=n.getValue(mode); // get const pointer to the values
1478 // get a non const pointer to the inside array of values and perform operation
1479 T * value=const_cast<T *> (result->getValue(mode));
1481 const T* lastvalue=value+numberOfElements; // pointing just after last value of result
1482 for ( ; value!=lastvalue ; ++value ) // loop on all elements
1484 *value=(T)0; // initialize value
1485 const T* endofRow=value1+NumberOfComponents; // pointing just after end of row
1486 for ( ; value1 != endofRow; ++value1, ++value2) // computation of dot product
1487 *value += (*value1) * (*value2);
1492 /*! Return L2 Norm of the field's component.
1493 * Cannot be applied to a field with a support on nodes.
1494 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1496 template <class T> double FIELD<T>::normL2(int component, const FIELD<double> * p_field_volume) const
1498 _checkNormCompatibility(p_field_volume); // may throw exception
1499 if ( component<1 || component>getNumberOfComponents() )
1500 throw MEDEXCEPTION(STRING("FIELD<T>::normL2() : The component argument should be between 1 and the number of components"));
1502 const FIELD<double> * p_field_size=p_field_volume;
1503 if(!p_field_volume) // if the user don't supply the volume
1504 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1506 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1507 const double* vol=p_field_size->getValue(MED_FULL_INTERLACE);
1508 const T* value=getValueI( MED_NO_INTERLACE, component); // get pointer to the component's values
1509 const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column
1511 double integrale=0.0;
1513 for (; value!=lastvalue ; ++value ,++vol)
1515 integrale += static_cast<double>((*value) * (*value)) * (*vol);
1519 if(!p_field_volume) // if the user didn't supply the volume
1520 delete p_field_size; // delete temporary volume field
1522 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1524 return integrale/totVol;
1527 /*! Return L2 Norm of the field.
1528 * Cannot be applied to a field with a support on nodes.
1529 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1531 template <class T> double FIELD<T>::normL2(const FIELD<double> * p_field_volume) const
1533 _checkNormCompatibility(p_field_volume); // may throw exception
1534 const FIELD<double> * p_field_size=p_field_volume;
1535 if(!p_field_volume) // if the user don't supply the volume
1536 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1538 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1539 const double* vol=p_field_size->getValue(MED_FULL_INTERLACE);
1540 const double* lastvol=vol+getNumberOfValues(); // pointing just after the end of vol
1541 const T* value=getValue( MED_NO_INTERLACE); // get pointer to the field's values
1544 const double* p_vol=vol;
1545 for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume
1548 double integrale=0.0;
1549 for (int i=1; i<=getNumberOfComponents(); ++i) // compute integral on all components
1550 for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol)
1551 integrale += static_cast<double>((*value) * (*value)) * (*p_vol);
1553 if(!p_field_volume) // if the user didn't supply the volume
1554 delete p_field_size; // delete temporary volume field
1556 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1558 return integrale/totVol;
1561 /*! Return L1 Norm of the field's component.
1562 * Cannot be applied to a field with a support on nodes.
1563 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1565 template <class T> double FIELD<T>::normL1(int component, const FIELD<double> * p_field_volume) const
1567 _checkNormCompatibility(p_field_volume); // may throw exception
1568 if ( component<1 || component>getNumberOfComponents() )
1569 throw MEDEXCEPTION(STRING("FIELD<T>::normL2() : The component argument should be between 1 and the number of components"));
1571 const FIELD<double> * p_field_size=p_field_volume;
1572 if(!p_field_volume) // if the user don't supply the volume
1573 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1575 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1576 const double* vol=p_field_size->getValue(MED_FULL_INTERLACE);
1577 const T* value=getValueI( MED_NO_INTERLACE, component); // get pointer to the component's values
1578 const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column
1580 double integrale=0.0;
1582 for (; value!=lastvalue ; ++value ,++vol)
1584 integrale += std::abs( static_cast<double>(*value) ) * (*vol);
1588 if(!p_field_volume) // if the user didn't supply the volume
1589 delete p_field_size; // delete temporary volume field
1591 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1593 return integrale/totVol;
1596 /*! Return L1 Norm of the field.
1597 * Cannot be applied to a field with a support on nodes.
1598 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1600 template <class T> double FIELD<T>::normL1(const FIELD<double> * p_field_volume) const
1602 _checkNormCompatibility(p_field_volume); // may throw exception
1603 const FIELD<double> * p_field_size=p_field_volume;
1604 if(!p_field_volume) // if the user don't supply the volume
1605 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1607 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1608 const double* vol=p_field_size->getValue(MED_FULL_INTERLACE);
1609 const double* lastvol=vol+getNumberOfValues(); // pointing just after the end of vol
1610 const T* value=getValue( MED_NO_INTERLACE); // get pointer to the field's values
1613 const double* p_vol=vol;
1614 for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume
1617 double integrale=0.0;
1618 for (int i=1; i<=getNumberOfComponents(); ++i) // compute integral on all components
1619 for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol)
1620 integrale += std::abs( static_cast<double>(*value) ) * (*p_vol);
1622 if(!p_field_volume) // if the user didn't supply the volume
1623 delete p_field_size; // delete temporary volume field
1625 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1627 return integrale/totVol;
1634 Constructor with parameters; the object is set via a file and its associated
1635 driver. For the moment only the MED_DRIVER is considered and if the last two
1636 argument (iterationNumber and orderNumber) are not set; their default value
1637 is -1. If the field fieldDriverName with the iteration number
1638 iterationNumber and the order number orderNumber does not exist in the file
1639 fieldDriverName; the constructor raises an exception.
1641 template <class T> FIELD<T>::FIELD(const SUPPORT * Support,
1642 driverTypes driverType,
1643 const string & fileName/*=""*/,
1644 const string & fieldDriverName/*=""*/,
1645 const int iterationNumber,
1646 const int orderNumber)
1647 throw (MEDEXCEPTION)
1649 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) : ";
1658 _value = (MEDARRAY<T>*)NULL;
1660 _iterationNumber = iterationNumber;
1662 _orderNumber = orderNumber;
1668 MED_FIELD_RDONLY_DRIVER<T> myDriver(fileName,this);
1669 myDriver.setFieldName(fieldDriverName);
1670 current = addDriver(myDriver);
1673 // current = addDriver(driverType,fileName,fieldDriverName);
1674 // switch(_drivers[current]->getAccessMode() ) {
1675 // case MED_WRONLY : {
1676 // MESSAGE("FIELD<T>::FIELD(driverTypes driverType, .....) : driverType must have a MED_RDONLY or MED_RDWR accessMode");
1677 // rmDriver(current);
1684 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Driver type unknown : can't create driver!"));
1689 _drivers[current]->open();
1690 _drivers[current]->read();
1691 _drivers[current]->close();
1699 template <class T> FIELD<T>::~FIELD()
1701 BEGIN_OF(" Destructeur FIELD<T>::~FIELD()");
1703 if (_value) delete _value;
1704 END_OF(" Destructeur FIELD<T>::~FIELD()");
1710 template <class T> void FIELD<T>::allocValue(const int NumberOfComponents)
1712 const char* LOC = "FIELD<T>::allocValue(const int NumberOfComponents)" ;
1715 _numberOfComponents = NumberOfComponents ;
1716 if (_componentsTypes == NULL)
1717 _componentsTypes = new int[NumberOfComponents] ;
1718 if (_componentsNames == NULL)
1719 _componentsNames = new string[NumberOfComponents];
1720 if (_componentsDescriptions == NULL)
1721 _componentsDescriptions = new string[NumberOfComponents];
1722 if (_componentsUnits == NULL)
1723 _componentsUnits = new UNIT[NumberOfComponents];
1724 if (_MEDComponentsUnits == NULL)
1725 _MEDComponentsUnits = new string[NumberOfComponents];
1726 for (int i=0;i<NumberOfComponents;i++) {
1727 _componentsTypes[i] = 0 ;
1731 _numberOfValues = _support->getNumberOfElements(MED_ALL_ELEMENTS);
1732 MESSAGE(LOC <<" : "<<_numberOfValues <<" et "<< NumberOfComponents);
1734 _value = new MEDARRAY<T>(_numberOfComponents,_numberOfValues);
1738 catch (MEDEXCEPTION &ex) {
1739 MESSAGE("No value defined, problem with NumberOfComponents (and may be _support) size of MEDARRAY<T>::_value !");
1740 _value = (MEDARRAY<T>*)NULL ;
1744 END_OF("void FIELD<T>::allocValue(const int NumberOfComponents)");
1750 template <class T> void FIELD<T>::allocValue(const int NumberOfComponents, const int LengthValue)
1752 BEGIN_OF("void FIELD<T>::allocValue(const int NumberOfComponents,const int LengthValue)");
1754 _numberOfComponents = NumberOfComponents ;
1755 if (_componentsTypes == NULL)
1756 _componentsTypes = new int[NumberOfComponents] ;
1757 if (_componentsNames == NULL)
1758 _componentsNames = new string[NumberOfComponents];
1759 if (_componentsDescriptions == NULL)
1760 _componentsDescriptions = new string[NumberOfComponents];
1761 if (_componentsUnits == NULL)
1762 _componentsUnits = new UNIT[NumberOfComponents];
1763 if (_MEDComponentsUnits == NULL)
1764 _MEDComponentsUnits = new string[NumberOfComponents];
1765 for (int i=0;i<NumberOfComponents;i++) {
1766 _componentsTypes[i] = 0 ;
1769 MESSAGE("FIELD : constructeur : "<<LengthValue <<" et "<< NumberOfComponents);
1770 _numberOfValues = LengthValue ;
1771 _value = new MEDARRAY<T>(_numberOfComponents,_numberOfValues);
1775 END_OF("void FIELD<T>::allocValue(const int NumberOfComponents,const int LengthValue)");
1781 template <class T> void FIELD<T>::deallocValue()
1783 BEGIN_OF("void FIELD<T>::deallocValue()");
1784 _numberOfValues = 0 ;
1785 _numberOfComponents = 0 ;
1789 END_OF("void FIELD<T>::deallocValue()");
1792 // -----------------
1794 // -----------------
1797 template <class T> FIELD<T>::INSTANCE_DE<MED_FIELD_RDWR_DRIVER<T> > FIELD<T>::inst_med ;
1799 template <class T> FIELD<T>::INSTANCE_DE<VTK_FIELD_DRIVER<T> > FIELD<T>::inst_vtk ;
1801 template <class T> const typename FIELD<T>::INSTANCE * const FIELD<T>::instances[] = { &FIELD<T>::inst_med, &FIELD<T>::inst_vtk} ;
1805 Create the specified driver and return its index reference to path to
1806 read or write methods.
1809 template <class T> int FIELD<T>::addDriver(driverTypes driverType,
1810 const string & fileName/*="Default File Name.med"*/,
1811 const string & driverName/*="Default Field Name"*/)
1813 const char * LOC = "FIELD<T>::addDriver(driverTypes driverType, const string & fileName=\"Default File Name.med\",const string & driverName=\"Default Field Name\") : ";
1817 int itDriver = (int) NO_DRIVER;
1823 SCRUTE(instances[driverType]);
1828 itDriver = (int) driverType ;
1837 case GIBI_DRIVER : {
1838 throw MED_EXCEPTION (LOCALIZED(STRING(LOC)<< "driverType other than MED_DRIVER and VTK_DRIVER has been specified to the method which is not allowed for the object FIELD"));
1843 throw MED_EXCEPTION (LOCALIZED(STRING(LOC)<< "driverType other than MED_DRIVER and VTK_DRIVER has been specified to the method which is not allowed for the object FIELD"));
1848 if (itDriver == ((int) NO_DRIVER))
1849 throw MED_EXCEPTION (LOCALIZED(STRING(LOC)<< "driverType other than MED_DRIVER and VTK_DRIVER has been specified to the method which is not allowed for the object FIELD"));
1851 driver = instances[itDriver]->run(fileName, this) ;
1853 _drivers.push_back(driver);
1855 current = _drivers.size()-1;
1857 _drivers[current]->setFieldName(driverName);
1866 Duplicate the given driver and return its index reference to path to
1867 read or write methods.
1869 template <class T> inline int FIELD<T>::addDriver (GENDRIVER & driver )
1871 const char * LOC = "FIELD<T>::addDriver(GENDRIVER &) : ";
1874 // duplicate driver to delete it with destructor !
1875 GENDRIVER * newDriver = driver.copy() ;
1877 _drivers.push_back(newDriver);
1878 return _drivers.size() -1 ;
1884 Remove the driver referenced by its index.
1886 template <class T> void FIELD<T>::rmDriver (int index/*=0*/)
1888 const char * LOC = "FIELD<T>::rmDriver (int index=0): ";
1891 if ( _drivers[index] ) {
1892 //_drivers.erase(&_drivers[index]);
1894 MESSAGE ("detruire");
1897 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
1898 << "The <index given is invalid, index must be between 0 and |"
1907 Read FIELD in the file specified in the driver given by its index.
1909 template <class T> inline void FIELD<T>::read(int index/*=0*/)
1911 const char * LOC = "FIELD<T>::read(int index=0) : ";
1914 if ( _drivers[index] ) {
1915 _drivers[index]->open();
1916 _drivers[index]->read();
1917 _drivers[index]->close();
1920 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
1921 << "The index given is invalid, index must be between 0 and |"
1929 Write FIELD in the file specified in the driver given by its index.
1931 template <class T> inline void FIELD<T>::write(int index/*=0*/, const string & driverName /*= ""*/)
1933 const char * LOC = "FIELD<T>::write(int index=0, const string & driverName = \"\") : ";
1936 if( _drivers[index] ) {
1937 _drivers[index]->open();
1938 if (driverName != "") _drivers[index]->setFieldName(driverName);
1939 _drivers[index]->write();
1940 _drivers[index]->close();
1943 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
1944 << "The index given is invalid, index must be between 0 and |"
1952 Write FIELD in the file specified in the driver given by its index. Use this
1953 method for ASCII drivers (e.g. VTK_DRIVER)
1955 template <class T> inline void FIELD<T>::writeAppend(int index/*=0*/, const string & driverName /*= ""*/)
1957 const char * LOC = "FIELD<T>::write(int index=0, const string & driverName = \"\") : ";
1960 if( _drivers[index] ) {
1961 _drivers[index]->openAppend();
1962 if (driverName != "") _drivers[index]->setFieldName(driverName);
1963 _drivers[index]->writeAppend();
1964 _drivers[index]->close();
1967 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
1968 << "The index given is invalid, index must be between 0 and |"
1977 Write FIELD with the driver which is equal to the given driver.
1981 template <class T> inline void FIELD<T>::write(const GENDRIVER & genDriver)
1983 const char * LOC = " FIELD<T>::write(const GENDRIVER &) : ";
1986 for (unsigned int index=0; index < _drivers.size(); index++ )
1987 if ( *_drivers[index] == genDriver ) {
1988 _drivers[index]->open();
1989 _drivers[index]->write();
1990 _drivers[index]->close();
1999 Write FIELD with the driver which is equal to the given driver.
2001 Use by MED object. Use this method for ASCII drivers (e.g. VTK_DRIVER).
2003 template <class T> inline void FIELD<T>::writeAppend(const GENDRIVER & genDriver)
2005 const char * LOC = " FIELD<T>::write(const GENDRIVER &) : ";
2008 for (unsigned int index=0; index < _drivers.size(); index++ )
2009 if ( *_drivers[index] == genDriver ) {
2010 _drivers[index]->openAppend();
2011 _drivers[index]->writeAppend();
2012 _drivers[index]->close();
2021 Read FIELD with the driver which is equal to the given driver.
2025 template <class T> inline void FIELD<T>::read(const GENDRIVER & genDriver)
2027 const char * LOC = " FIELD<T>::read(const GENDRIVER &) : ";
2030 for (unsigned int index=0; index < _drivers.size(); index++ )
2031 if ( *_drivers[index] == genDriver ) {
2032 _drivers[index]->open();
2033 _drivers[index]->read();
2034 _drivers[index]->close();
2043 Destroy the MEDARRAY<T> in FIELD and put the new one without copy.
2046 template <class T> inline void FIELD<T>::setValue(MEDARRAY<T> *Value)
2048 if (NULL != _value) delete _value ;
2054 Return a reference to the MEDARRAY<T> in FIELD.
2057 template <class T> inline MEDARRAY<T>* FIELD<T>::getvalue() const
2063 Return a reference to values array to read them.
2065 template <class T> inline const T* FIELD<T>::getValue(medModeSwitch Mode) const
2067 return _value->get(Mode) ;
2071 Return a reference to i^{th} row or column - component - (depend on Mode value)
2072 of FIELD values array.
2074 template <class T> inline const T* FIELD<T>::getValueI(medModeSwitch Mode,int i) const
2076 if ( Mode == MED_FULL_INTERLACE )
2078 return _value->getRow(i) ;
2080 ASSERT ( Mode == MED_NO_INTERLACE);
2081 return _value->getColumn(i);
2085 Return the value of i^{th} element and j^{th} component.
2087 template <class T> inline T FIELD<T>::getValueIJ(int i,int j) const
2089 return _value->getIJ(i,j) ;
2093 Copy new values array in FIELD according to the given mode.
2095 Array must have right size. If not results are unpredicable.
2097 template <class T> inline void FIELD<T>::setValue(medModeSwitch mode, T* value)
2099 _value->set(mode,value);
2103 Update values array in FIELD with the given ones according to specified mode.
2105 template <class T> inline void FIELD<T>::setValueI(medModeSwitch mode, int i, T* value)
2108 if (MED_FULL_INTERLACE == mode)
2109 _value->setI(i,value);
2110 else if (MED_NO_INTERLACE == mode)
2111 _value->setJ(i,value);
2113 throw MEDEXCEPTION(LOCALIZED("FIELD<T>::setValueI : bad medModeSwitch")) ;
2117 Set the value of i^{th} element and j^{th} component with the given one.
2119 template <class T> inline void FIELD<T>::setValueIJ(int i, int j, T value)
2121 _value->setIJ(i,j,value);
2129 Fill values array with volume values.
2131 template <class T> void FIELD<T>::getVolume() const throw (MEDEXCEPTION)
2133 const char * LOC = "FIELD<double>::getVolume() const : ";
2136 // The field has to be initilised by a non empty support and a
2137 // number of components = 1 and its value type has to be set to MED_REEL64
2138 // (ie a FIELD<double>)
2140 if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_REEL64))
2141 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"));
2147 Fill values array with area values.
2149 template <class T> void FIELD<T>::getArea() const throw (MEDEXCEPTION)
2151 const char * LOC = "FIELD<double>::getArea() const : ";
2154 // The field has to be initilised by a non empty support and a
2155 // number of components = 1 and its value type has to be set to MED_REEL64
2156 // (ie a FIELD<double>)
2158 if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_REEL64))
2159 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"));
2165 Fill values array with length values.
2167 template <class T> void FIELD<T>::getLength() const throw (MEDEXCEPTION)
2169 const char * LOC = "FIELD<double>::getLength() const : ";
2172 // The field has to be initilised by a non empty support and a
2173 // number of components = 1 and its value type has to be set to MED_REEL64
2174 // (ie a FIELD<double>)
2176 if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_REEL64))
2177 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"));
2183 Fill values array with normal values.
2185 template <class T> void FIELD<T>::getNormal() const throw (MEDEXCEPTION)
2187 const char * LOC = "FIELD<double>::getNormal() const : ";
2190 // The field has to be initilised by a non empty support and a
2191 // number of components = 1 and its value type has to be set to MED_REEL64
2192 // (ie a FIELD<double>)
2194 if (_support == (SUPPORT *) NULL)
2195 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"));
2197 int dim_space = _support->getMesh()->getSpaceDimension();
2199 if ((_numberOfComponents != dim_space) || (_valueType != MED_REEL64))
2200 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"));
2206 Fill values array with barycenter values.
2208 template <class T> void FIELD<T>::getBarycenter() const throw (MEDEXCEPTION)
2210 const char * LOC = "FIELD<double>::getBarycenter() const : ";
2213 // The field has to be initilised by a non empty support and a number of
2214 //components = space dimension and its value type has to be set to MED_REEL64
2215 // (ie a FIELD<double>)
2217 if (_support == (SUPPORT *) NULL)
2218 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"));
2220 int dim_space = _support->getMesh()->getSpaceDimension();
2222 if ((_numberOfComponents != dim_space) || (_valueType != MED_REEL64))
2223 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"));
2228 #endif /* FIELD_HXX */