]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_Field.hxx
Salome HOME
32c17117a97095c8a030a8e475bde153683a5dcd
[modules/med.git] / src / MEDMEM / MEDMEM_Field.hxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/
19 //
20 /*
21  File Field.hxx
22  $Header$
23 */
24
25 #ifndef FIELD_HXX
26 #define FIELD_HXX
27
28 #include <vector>
29 #include <map>
30 #include <algorithm>
31 #include <math.h>
32 #include <cmath>
33
34 #include "MEDMEM_Utilities.hxx"
35 #include "MEDMEM_Exception.hxx"
36 #include "MEDMEM_define.hxx"
37 #include "MEDMEM_Support.hxx"
38 #include "MEDMEM_Unit.hxx"
39 #include "MEDMEM_nArray.hxx"
40 #include "MEDMEM_GenDriver.hxx"
41 #include "MEDMEM_ArrayInterface.hxx"
42 #include "MEDMEM_SetInterlacingType.hxx"
43 #include "MEDMEM_FieldForward.hxx"
44 #include "MEDMEM_GaussLocalization.hxx"
45
46 /*!
47
48   This class contains all the informations related with a template class FIELD :
49   - Components descriptions
50   - Time step description
51   - Location of the values (a SUPPORT class)
52
53 */
54
55 namespace MEDMEM {
56
57   template < typename T > struct SET_VALUE_TYPE {
58     static const MED_EN::med_type_champ _valueType = MED_EN::MED_UNDEFINED_TYPE;};
59   template < > struct SET_VALUE_TYPE<double> {
60     static const MED_EN::med_type_champ _valueType = MED_EN::MED_REEL64; };
61   template < > struct SET_VALUE_TYPE<int> {
62     static const MED_EN::med_type_champ _valueType = MED_EN::MED_INT32; };
63
64 class FIELD_    // GENERIC POINTER TO a template <class T, class INTERLACING_TAG> class FIELD
65 {
66 protected:
67
68   bool            _isRead ;
69
70   /*!
71     \if developper
72     Field name.
73     \endif
74   */
75   string          _name ;
76   /*!
77     \if developper
78     Field description.
79     \endif
80   */
81   string          _description ;
82   /*!
83     \if developper
84     Pointer to the support the field deals with.
85     \endif
86   */
87   const SUPPORT * _support ;
88
89   /*!
90     \if developper
91     Number of field's components.
92     \endif
93   */
94   int             _numberOfComponents ;
95   /*!
96     \if developper
97     Number of field's values.
98     doesn't take care of _numberOfComponents
99     and number of Gauss points.
100     \endif
101   */
102   int             _numberOfValues ;
103
104   /*!
105     \if developper
106     Array of size _numberOfComponents. \n
107     (constant, scalar, vector, tensor)\n
108     We could use an array of integer to store
109     numbers of values: \n
110     - 1 for scalar,\n
111     - space dimension for vector,\n
112     - space dimension square for tensor.\n
113     So numbers of values per entities would be
114     sum of _componentsTypes array.
115
116     Not implemented yet! All type are scalar !
117     \endif
118   */
119   int *           _componentsTypes ;
120   /*!
121     \if developper
122     Array of size _numberOfComponents
123     storing components names if any.
124     \endif
125   */
126   string *        _componentsNames;
127   /*!
128     \if developper
129     Array of size _numberOfComponents
130     storing components descriptions if any.
131     \endif
132  */
133   string *        _componentsDescriptions;
134   /*!
135     \if developper
136     Array of size _numberOfComponents
137     storing components units if any.
138     \endif
139  */
140   UNIT *          _componentsUnits;
141   /*!
142     \if developper
143     Array of size _numberOfComponents
144     storing components units if any.
145     \endif
146   */
147   string *        _MEDComponentsUnits;
148   /*!
149     \if developper
150     Iteration number of the field.
151     \endif
152   */
153   int             _iterationNumber ;
154   /*!
155     \if developper
156     Time of the field.
157     \endif
158   */
159   double          _time;
160   /*!
161     \if developper
162     Order number of the field.
163     \endif
164   */
165   int             _orderNumber ;
166   /*!
167     \if developper
168     At the initialization step of the field using the constructors; this attribute,
169     the value type (integer or real) , is set automatically. There is a get method
170     but not a set method for this attribute.
171     \endif
172   */
173   MED_EN::med_type_champ _valueType ;
174   /*!
175     \if developper
176     At the initialization step of the field using the constructors; this attribute,
177     the interlacing type (full interlace or no interlace field value storage), is set
178     automatically. There is a get method but not a set method for this attribute.
179     \endif
180   */
181   MED_EN::medModeSwitch _interlacingType;
182
183   vector<GENDRIVER *> _drivers; // Storage of the drivers currently in use
184   static void _checkFieldCompatibility(const FIELD_& m, const FIELD_& n, bool checkUnit=true) throw (MEDEXCEPTION);
185   static void _deepCheckFieldCompatibility(const FIELD_& m, const FIELD_& n, bool checkUnit=true) throw (MEDEXCEPTION);
186   void _checkNormCompatibility(const FIELD<double>* p_field_volume=NULL) const  throw (MEDEXCEPTION);
187   FIELD<double>* _getFieldSize() const;
188
189 public:
190
191   friend class MED_MED_RDONLY_DRIVER21;
192   friend class MED_MED_WRONLY_DRIVER21;
193   friend class MED_MED_RDWR_DRIVER21;
194   friend class MED_MED_RDONLY_DRIVER22;
195   friend class MED_MED_WRONLY_DRIVER22;
196   friend class MED_MED_RDWR_DRIVER22;
197   friend class VTK_MED_DRIVER;
198
199   /*!
200     Constructor.
201   */
202   FIELD_ ();
203   /*!
204     Constructor.
205   */
206   FIELD_(const SUPPORT * Support, const int NumberOfComponents);
207   /*!
208     Copy constructor.
209   */
210   FIELD_(const FIELD_ &m);
211
212   /*!
213     Destructor.
214   */
215   virtual ~FIELD_();
216
217  FIELD_& operator=(const FIELD_ &m);
218
219   virtual  void     rmDriver(int index=0);
220   virtual   int     addDriver(driverTypes driverType,
221                               const string & fileName="Default File Name.med",
222                               const string & driverFieldName="Default Field Nam",
223                               MED_EN::med_mode_acces access=MED_EN::MED_REMP) ;
224
225   virtual  int      addDriver( GENDRIVER & driver);
226   virtual  void     read (const GENDRIVER &);
227   virtual  void     read(int index=0);
228   virtual  void     openAppend( void );
229   virtual  void     write(const GENDRIVER &);
230   virtual  void     write(int index=0, const string & driverName="");
231
232   virtual  void     writeAppend(const GENDRIVER &);
233   virtual  void     writeAppend(int index=0, const string & driverName="");
234
235   inline void     setName(const string Name);
236   inline string   getName() const;
237   inline void     setDescription(const string Description);
238   inline string   getDescription() const;
239   inline const SUPPORT * getSupport() const;
240   inline void     setSupport(const SUPPORT * support);
241   inline void     setNumberOfComponents(const int NumberOfComponents);
242   inline int      getNumberOfComponents() const;
243   inline void     setNumberOfValues(const int NumberOfValues);
244   inline int      getNumberOfValues() const;
245   //    inline void     setComponentType(int *ComponentType);
246   //    inline int *    getComponentType() const;
247   //    inline int      getComponentTypeI(int i) const;
248   inline void     setComponentsNames(const string * ComponentsNames);
249   inline void     setComponentName(int i, const string ComponentName);
250   inline const string * getComponentsNames() const;
251   inline string   getComponentName(int i) const;
252   inline void     setComponentsDescriptions(const string * ComponentsDescriptions);
253   inline void     setComponentDescription(int i, const string ComponentDescription);
254   inline const string * getComponentsDescriptions() const;
255   inline string   getComponentDescription(int i) const;
256
257   // provisoire : en attendant de regler le probleme des unites !
258   inline void     setComponentsUnits(const UNIT * ComponentsUnits);
259   inline const UNIT *   getComponentsUnits() const;
260   inline const UNIT *   getComponentUnit(int i) const;
261   inline void     setMEDComponentsUnits(const string * MEDComponentsUnits);
262   inline void     setMEDComponentUnit(int i, const string MEDComponentUnit);
263   inline const string * getMEDComponentsUnits() const;
264   inline string   getMEDComponentUnit(int i) const;
265
266   inline void     setIterationNumber(int IterationNumber);
267   inline int      getIterationNumber() const;
268   inline void     setTime(double Time);
269   inline double   getTime() const;
270   inline void     setOrderNumber(int OrderNumber);
271   inline int      getOrderNumber() const;
272
273   inline MED_EN::med_type_champ getValueType () const;
274   inline MED_EN::medModeSwitch  getInterlacingType() const;
275   virtual inline bool getGaussPresence() const throw (MEDEXCEPTION);
276 protected:
277   void copyGlobalInfo(const FIELD_& m);
278 };
279
280 // ---------------------------------
281 // Implemented Methods : constructor
282 // ---------------------------------
283
284 // -----------------
285 // Methodes Inline
286 // -----------------
287 /*!
288   Set FIELD name.
289 */
290 inline void FIELD_::setName(const string Name)
291 {
292   _name=Name;
293 }
294 /*!
295   Get FIELD name.
296 */
297 inline string FIELD_::getName() const
298 {
299   return _name;
300 }
301 /*!
302   Set FIELD description.
303 */
304 inline void FIELD_::setDescription(const string Description)
305 {
306   _description=Description;
307 }
308 /*!
309   Get FIELD description.
310 */
311 inline string FIELD_::getDescription() const
312 {
313   return _description;
314 }
315 /*!
316   Set FIELD number of components.
317 */
318 inline void FIELD_::setNumberOfComponents(const int NumberOfComponents)
319 {
320   _numberOfComponents=NumberOfComponents;
321 }
322 /*!
323   Get FIELD number of components.
324 */
325 inline int FIELD_::getNumberOfComponents() const
326 {
327   return _numberOfComponents ;
328 }
329 /*!
330   Set FIELD number of values.
331
332   It must be the same than in the associated SUPPORT object.
333 */
334 inline void FIELD_::setNumberOfValues(const int NumberOfValues)
335 {
336   _numberOfValues=NumberOfValues;
337 }
338 /*!
339   Get FIELD number of value.
340 */
341 inline int FIELD_::getNumberOfValues() const
342 {
343   return _numberOfValues ;
344 }
345
346 //  inline void FIELD_::setComponentType(int *ComponentType)
347 //  {
348 //    _componentsTypes=ComponentType ;
349 //  }
350 //  inline int * FIELD_::getComponentType() const
351 //  {
352 //    return _componentsTypes ;
353 //  }
354 //  inline int FIELD_::getComponentTypeI(int i) const
355 //  {
356 //    return _componentsTypes[i-1] ;
357 //  }
358
359 /*!
360   Set FIELD components names.
361
362   Duplicate the ComponentsNames string array to put components names in
363   FIELD. ComponentsNames size must be equal to number of components.
364 */
365 inline void FIELD_::setComponentsNames(const string * ComponentsNames)
366 {
367   if (NULL == _componentsNames)
368     _componentsNames = new string[_numberOfComponents] ;
369   for (int i=0; i<_numberOfComponents; i++)
370     _componentsNames[i]=ComponentsNames[i] ;
371 }
372 /*!
373   Set FIELD i^th component name.
374
375   i must be >=1 and <= number of components.
376 */
377 inline void FIELD_::setComponentName(int i, const string ComponentName)
378 {
379   _componentsNames[i-1]=ComponentName ;
380 }
381 /*!
382   Get a reference to the string array which contain the components names.
383
384   This Array size is equal to number of components
385 */
386 inline const string * FIELD_::getComponentsNames() const
387 {
388   return _componentsNames ;
389 }
390 /*!
391   Get the name of the i^th component.
392 */
393 inline string FIELD_::getComponentName(int i) const
394 {
395   return _componentsNames[i-1] ;
396 }
397 /*!
398   Set FIELD components descriptions.
399
400   Duplicate the ComponentsDescriptions string array to put components
401   descriptions in FIELD.
402   ComponentsDescriptions size must be equal to number of components.
403 */
404 inline void FIELD_::setComponentsDescriptions(const string * ComponentsDescriptions)
405 {
406   if (NULL == _componentsDescriptions)
407     _componentsDescriptions = new string[_numberOfComponents] ;
408   for (int i=0; i<_numberOfComponents; i++)
409     _componentsDescriptions[i]=ComponentsDescriptions[i] ;
410 }
411 /*!
412   Set FIELD i^th component description.
413
414   i must be >=1 and <= number of components.
415 */
416 inline void FIELD_::setComponentDescription(int i,const string ComponentDescription)
417 {
418   _componentsDescriptions[i-1]=ComponentDescription ;
419 }
420 /*!
421   Get a reference to the string array which contain the components descriptions.
422
423   This Array size is equal to number of components
424 */
425 inline const string * FIELD_::getComponentsDescriptions() const
426 {
427   return _componentsDescriptions ;
428 }
429 /*!
430   Get the description of the i^th component.
431 */
432 inline string FIELD_::getComponentDescription(int i) const
433 {
434   return _componentsDescriptions[i-1];
435 }
436
437 /*!
438   \todo
439   Set FIELD components UNIT.
440
441   Duplicate the ComponentsUnits UNIT array to put components
442   units in FIELD.
443   ComponentsUnits size must be equal to number of components.
444 */
445 inline void FIELD_::setComponentsUnits(const UNIT * ComponentsUnits)
446 {
447   if (NULL == _componentsUnits)
448     _componentsUnits = new UNIT[_numberOfComponents] ;
449   for (int i=0; i<_numberOfComponents; i++)
450     _componentsUnits[i]=ComponentsUnits[i] ;
451 }
452 /*!
453   Get a reference to the UNIT array which contain the components units.
454
455   This Array size is equal to number of components
456 */
457 inline const UNIT * FIELD_::getComponentsUnits() const
458 {
459   return _componentsUnits ;
460 }
461 /*!
462   Get the UNIT of the i^th component.
463 */
464 inline const UNIT * FIELD_::getComponentUnit(int i) const
465 {
466   return &_componentsUnits[i-1] ;
467 }
468 /*!
469   Set FIELD components unit.
470
471   Duplicate the MEDComponentsUnits string array to put components
472   units in FIELD.
473   MEDComponentsUnits size must be equal to number of components.
474
475 */
476 inline void FIELD_::setMEDComponentsUnits(const string * MEDComponentsUnits)
477 {
478   if (NULL == _MEDComponentsUnits)
479     _MEDComponentsUnits = new string[_numberOfComponents] ;
480   for (int i=0; i<_numberOfComponents; i++)
481     _MEDComponentsUnits[i]=MEDComponentsUnits[i] ;
482 }
483 /*!
484   Set FIELD i^th component unit.
485
486   i must be >=1 and <= number of components.
487 */
488 inline void FIELD_::setMEDComponentUnit(int i, const string MEDComponentUnit)
489 {
490   _MEDComponentsUnits[i-1]=MEDComponentUnit ;
491 }
492 /*!
493   Get a reference to the string array which contain the components units.
494
495   This Array size is equal to number of components
496 */
497 inline const string * FIELD_::getMEDComponentsUnits() const
498 {
499   return _MEDComponentsUnits ;
500 }
501 /*!
502   Get the string for unit of the i^th component.
503 */
504 inline string FIELD_::getMEDComponentUnit(int i) const
505 {
506   return _MEDComponentsUnits[i-1] ;
507 }
508 /*!
509   Set the iteration number where FIELD has been calculated.
510 */
511 inline void FIELD_::setIterationNumber(int IterationNumber)
512 {
513   _iterationNumber=IterationNumber;
514 }
515 /*!
516   Get the iteration number where FIELD has been calculated.
517 */
518 inline int FIELD_::getIterationNumber() const
519 {
520   return _iterationNumber ;
521 }
522 /*!
523   Set the time (in second) where FIELD has been calculated.
524 */
525 inline void FIELD_::setTime(double Time)
526 {
527   _time=Time ;
528 }
529 /*!
530   Get the time (in second) where FIELD has been calculated.
531 */
532 inline double FIELD_::getTime() const
533 {
534   return _time ;
535 }
536 /*!
537   Set the order number where FIELD has been calculated.
538
539   It corresponds to internal iteration during one time step.
540 */
541 inline void FIELD_::setOrderNumber(int OrderNumber)
542 {
543   _orderNumber=OrderNumber ;
544 }
545 /*!
546   Get the order number where FIELD has been calculated.
547 */
548 inline int FIELD_::getOrderNumber() const
549 {
550   return _orderNumber ;
551 }
552 /*!
553   Get a reference to the SUPPORT object associated to FIELD.
554 */
555 inline  const SUPPORT * FIELD_::getSupport() const
556 {
557   return _support ;
558 }
559 /*!
560   Set the reference to the SUPPORT object associated to FIELD.
561
562   Reference is not duplicate, so it must not be deleted.
563 */
564 inline void FIELD_::setSupport(const SUPPORT * support)
565 {
566   //A.G. Addings for RC
567   if(_support)
568     _support->removeReference();
569   _support = support ;
570   if(_support)
571     _support->addReference();
572 }
573 /*!
574   Get the FIELD med value type (MED_INT32 or MED_REEL64).
575 */
576 inline MED_EN::med_type_champ FIELD_::getValueType () const
577 {
578   return _valueType ;
579 }
580
581 /*!
582   Get the FIELD med interlacing type (MED_FULL_INTERLACE or MED_NO_INTERLACE).
583 */
584   inline MED_EN::medModeSwitch FIELD_::getInterlacingType () const
585 {
586   return _interlacingType ;
587 }
588
589 /*!
590   Get the FIELD gauss presence.
591 */
592   inline bool  FIELD_::getGaussPresence() const throw (MEDEXCEPTION)
593 {
594   const char * LOC = "FIELD_::getGaussPresence() : ";
595   throw MEDEXCEPTION(STRING(LOC) << " This FIELD_ doesn't rely on a FIELD<T>" );
596 }
597
598 } //End namespace MEDMEM
599
600 /////////////////////////
601 // END OF CLASS FIELD_ //
602 /////////////////////////
603
604 /*!
605
606   This template class contains informations related with a FIELD :
607   - Values of the field, their type (real or integer), the storage mode (full interlace or
608     no interlace).
609
610 */
611
612 namespace MEDMEM {
613
614   template<class T2> class MED_FIELD_RDONLY_DRIVER21;
615   template<class T2> class MED_FIELD_WRONLY_DRIVER21;
616   template<class T2> class MED_FIELD_RDONLY_DRIVER22;
617   template<class T2> class MED_FIELD_WRONLY_DRIVER22;
618   template<class T2> class VTK_FIELD_DRIVER;
619
620   template <class T,
621             class INTERLACING_TAG
622             > class FIELD : public FIELD_
623 {
624 protected:
625
626   typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,NoGauss>::Array ArrayNoGauss;
627   typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,Gauss>::Array   ArrayGauss;
628   typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array     ArrayNo;
629   typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array   ArrayFull;
630   typedef MEDMEM_Array_ Array;
631   typedef T ElementType;
632   typedef INTERLACING_TAG InterlacingTag;
633   typedef map<MED_EN::medGeometryElement,GAUSS_LOCALIZATION_*> locMap;
634
635   // array of value of type T
636   Array *_value ;
637
638   map<MED_EN::medGeometryElement,GAUSS_LOCALIZATION_*> _gaussModel; //A changer quand les drivers seront template de l'entrelacement
639
640   static T _scalarForPow;
641   static T pow(T x);
642
643 private:
644   void _operation(const FIELD& m,const FIELD& n, char* Op);
645   void _operationInitialize(const FIELD& m,const FIELD& n, char* Op);
646   void _add_in_place(const FIELD& m,const FIELD& n);
647   void _sub_in_place(const FIELD& m,const FIELD& n);
648   void _mul_in_place(const FIELD& m,const FIELD& n);
649   void _div_in_place(const FIELD& m,const FIELD& n) throw (MEDEXCEPTION);
650   //setValueType() ;
651
652 public:
653   FIELD();
654   FIELD(const FIELD &m);
655   FIELD(const SUPPORT * Support, const int NumberOfComponents)  throw (MEDEXCEPTION) ;
656   FIELD( driverTypes driverType,
657          const string & fileName, const string & fieldDriverName,
658          const int iterationNumber=-1, const int orderNumber=-1)
659     throw (MEDEXCEPTION);
660   FIELD(const SUPPORT * Support, driverTypes driverType,
661         const string & fileName="", const string & fieldName="",
662         const int iterationNumber = -1, const int orderNumber = -1)
663     throw (MEDEXCEPTION);
664   ~FIELD();
665
666   FIELD & operator=(const FIELD &m);
667
668   const FIELD operator+(const FIELD& m) const;
669   const FIELD operator-(const FIELD& m) const;
670   const FIELD operator*(const FIELD& m) const;
671   const FIELD operator/(const FIELD& m) const;
672   const FIELD operator-() const;
673   FIELD& operator+=(const FIELD& m);
674   FIELD& operator-=(const FIELD& m);
675   FIELD& operator*=(const FIELD& m);
676   FIELD& operator/=(const FIELD& m);
677   static FIELD* add(const FIELD& m, const FIELD& n);
678   static FIELD* addDeep(const FIELD& m, const FIELD& n);
679   static FIELD* sub(const FIELD& m, const FIELD& n);
680   static FIELD* subDeep(const FIELD& m, const FIELD& n);
681   static FIELD* mul(const FIELD& m, const FIELD& n);
682   static FIELD* mulDeep(const FIELD& m, const FIELD& n);
683   static FIELD* div(const FIELD& m, const FIELD& n);
684   static FIELD* divDeep(const FIELD& m, const FIELD& n);
685   double normMax() const throw (MEDEXCEPTION);
686   double norm2() const throw (MEDEXCEPTION);
687   void   applyLin(T a, T b);
688   template <T T_function(T)> void applyFunc();
689   void applyPow(T scalar);
690   static FIELD* scalarProduct(const FIELD& m, const FIELD& n, bool deepCheck=false);
691   double normL2(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
692   double normL2(const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
693   double normL1(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
694   double normL1(const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
695   FIELD* extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION);
696
697   friend class MED_FIELD_RDONLY_DRIVER21<T>;
698   friend class MED_FIELD_WRONLY_DRIVER21<T>;
699   friend class MED_FIELD_RDONLY_DRIVER22<T>;
700   friend class MED_FIELD_WRONLY_DRIVER22<T>;
701   friend class VTK_FIELD_DRIVER<T>;
702   //friend class MED_FIELD_RDWR_DRIVER  <T>;
703
704   void init ();
705   void rmDriver(int index=0);
706   int  addDriver(driverTypes driverType,
707                  const string & fileName="Default File Name.med",
708                  const string & driverFieldName="Default Field Name",
709                  MED_EN::med_mode_acces access=MED_EN::MED_REMP) ;
710
711   int  addDriver(GENDRIVER & driver);
712
713   void allocValue(const int NumberOfComponents);
714   void allocValue(const int NumberOfComponents, const int LengthValue);
715
716   void deallocValue();
717
718   inline void read(int index=0);
719   inline void read(const GENDRIVER & genDriver);
720   inline void write(int index=0, const string & driverName = "");
721   inline void write(const GENDRIVER &);
722
723   inline void writeAppend(int index=0, const string & driverName = "");
724   inline void writeAppend(const GENDRIVER &);
725
726   inline MEDMEM_Array_  * getArray()        const throw (MEDEXCEPTION);
727   inline ArrayGauss     * getArrayGauss()   const throw (MEDEXCEPTION);
728   inline ArrayNoGauss   * getArrayNoGauss() const throw (MEDEXCEPTION);
729   inline bool            getGaussPresence() const throw (MEDEXCEPTION);
730
731   inline int          getValueLength() const throw (MEDEXCEPTION);
732   inline const T*     getValue()       const throw (MEDEXCEPTION);
733   inline const T*     getRow(int i)    const throw (MEDEXCEPTION);
734   inline const T*     getColumn(int j) const throw (MEDEXCEPTION);
735   inline T            getValueIJ(int i,int j) const throw (MEDEXCEPTION);
736   inline T            getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION);
737
738   bool                getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION);
739
740   const int   getNumberOfGeometricTypes() const throw (MEDEXCEPTION);
741   const GAUSS_LOCALIZATION<INTERLACING_TAG> & getGaussLocalization(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
742   const int * getNumberOfGaussPoints() const throw (MEDEXCEPTION);
743   const int   getNumberOfGaussPoints( MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
744   const int   getNbGaussI(int i)          const throw (MEDEXCEPTION);
745   const int * getNumberOfElements()       const throw (MEDEXCEPTION);
746   const MED_EN::medGeometryElement  * getGeometricTypes()  const throw (MEDEXCEPTION);
747   bool        isOnAllElements()           const throw (MEDEXCEPTION);
748  
749   inline void setArray(MEDMEM_Array_ *value) throw (MEDEXCEPTION);
750   inline void setValue( T* value) throw (MEDEXCEPTION);
751   inline void setRow( int i, T* value) throw (MEDEXCEPTION);
752   inline void setColumn( int i, T* value) throw (MEDEXCEPTION);
753   inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION);
754
755   /*!
756     This fonction feeds the FIELD<double> private attributs _value with the
757     volume of each cells belonging to the argument Support. The field has to be
758     initialised via the constructor FIELD<double>(const SUPPORT * , const int )
759     with Support as SUPPORT argument, 1 has the number of components, and Support
760     has be a SUPPORT on 3D cells. This initialisation could be done by the empty
761     constructor followed by a setSupport and setNumberOfComponents call.
762    */
763   void getVolume() const throw (MEDEXCEPTION) ;
764   /*!
765     This fonction feeds the FIELD<double> private attributs _value with the
766     area of each cells (or faces) belonging to the attribut _support. The field
767     has to be initialised via the constructor FIELD<double>(const SUPPORT * ,
768     const int ) with 1 has the number of components, and _support has be a
769     SUPPORT on 2D cells or 3D faces. This initialisation could be done by the
770     empty constructor followed by a setSupport and setNumberOfComponents call.
771    */
772   void getArea() const throw (MEDEXCEPTION) ;
773   /*!
774     This fonction feeds the FIELD<double> private attributs _value with the
775     length of each segments belonging to the attribut _support. The field has
776     to be initialised via the constructor FIELD<double>(const SUPPORT * ,
777     const int ) with 1 has the number of components, and _support has be a
778     SUPPORT on 3D edges or 2D faces. This initialisation could be done by the
779     empty constructor followed by a setSupport and setNumberOfComponents call.
780    */
781   void getLength() const throw (MEDEXCEPTION) ;
782   /*!
783     This fonction feeds the FIELD<double> private attributs _value with the
784     normal vector of each faces belonging to the attribut _support. The field
785     has to be initialised via the constructor FIELD<double>(const SUPPORT * ,
786     const int ) with the space dimension has the number of components, and
787     _support has be a SUPPORT on 3D or 2D faces. This initialisation could be done
788     by the empty constructor followed by a setSupport and setNumberOfComponents
789     call.
790    */
791   void getNormal() const throw (MEDEXCEPTION) ;
792   /*!
793     This fonction feeds the FIELD<double> private attributs _value with the
794     barycenter of each faces or cells or edges belonging to the attribut _support.
795     The field has to be initialised via the constructor
796     FIELD<double>(const SUPPORT * ,const int ) with the space dimension has the
797     number of components, and _support has be a SUPPORT on 3D cells or 2D faces.
798     This initialisation could be done by the empty constructor followed by a
799     setSupport and setNumberOfComponents call.
800    */
801   void getBarycenter() const throw (MEDEXCEPTION) ;
802
803   typedef void (*myFuncType)(const double *,T*);
804   void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION);
805 };
806 }
807
808 #include "MEDMEM_DriverFactory.hxx"
809
810 namespace MEDMEM {
811
812 template <class T,class INTERLACING_TAG> T FIELD<T, INTERLACING_TAG>::_scalarForPow=1;
813
814 // --------------------
815 // Implemented Methods
816 // --------------------
817
818 /*!
819   Constructor with no parameter, most of the attribut members are set to NULL.
820 */
821 template <class T, class INTERLACING_TAG>
822 FIELD<T, INTERLACING_TAG>::FIELD():FIELD_()
823 {
824   MESSAGE("Constructeur FIELD sans parametre");
825
826   //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
827   ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE);
828   FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
829
830   //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
831   ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE);
832   FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
833
834   _value = ( ArrayNoGauss * ) NULL;
835 }
836
837 /*!
838   Constructor with parameters such that all attrribut are set but the _value
839   attribut is allocated but not set.
840 */
841 template <class T, class INTERLACING_TAG>
842 FIELD<T, INTERLACING_TAG>::FIELD(const SUPPORT * Support,
843                                     const int NumberOfComponents) throw (MEDEXCEPTION) :
844   FIELD_(Support, NumberOfComponents),_value(NULL)
845 {
846   BEGIN_OF("FIELD<T>::FIELD(const SUPPORT * Support, const int NumberOfComponents)");
847   SCRUTE(this);
848
849   //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
850   ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE)
851   FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
852
853   //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
854   ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE)
855   FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
856
857   try {
858     // becarefull about the numbre of gauss point
859     _numberOfValues = Support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
860   }
861 #ifdef _DEBUG_
862   catch (MEDEXCEPTION &ex) {
863 #else
864   catch (MEDEXCEPTION ) {
865 #endif
866     MESSAGE("No value defined ! ("<<ex.what()<<")");
867   }
868   MESSAGE("FIELD : constructeur : "<< _numberOfValues <<" et "<< NumberOfComponents);
869   if (0<_numberOfValues) {
870     _value = new ArrayNoGauss (_numberOfComponents,_numberOfValues);
871     _isRead = true ;
872   }
873
874   END_OF("FIELD<T>::FIELD(const SUPPORT * Support, const int NumberOfComponents)");
875 }
876
877 /*!
878   \if developper
879   \endif
880 */
881 template <class T, class INTERLACING_TAG> void FIELD<T, INTERLACING_TAG>::init ()
882 {
883 }
884
885 /*!
886   Copy constructor.
887 */
888 template <class T, class INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::FIELD(const FIELD & m):
889   FIELD_((FIELD_) m)
890 {
891   MESSAGE("Constructeur FIELD de recopie");
892
893   // RECOPIE PROFONDE <> de l'operateur= Rmq from EF
894   if (m._value != NULL)
895     {
896       if ( m.getGaussPresence() )
897         _value = new ArrayGauss( *(dynamic_cast< ArrayGauss * > (m._value) ) ,false);
898       else
899         _value = new ArrayNoGauss( *(dynamic_cast< ArrayNoGauss * > (m._value)) ,false);
900     }
901   else
902     _value = (ArrayNoGauss *) NULL;
903   locMap::const_iterator it;
904   for ( it = m._gaussModel.begin();it != m._gaussModel.end(); it++ )
905     _gaussModel[dynamic_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ((*it).second)->getType()]=
906       new GAUSS_LOCALIZATION<INTERLACING_TAG>(
907                                               *dynamic_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ( (*it).second )
908                                               );
909
910   _valueType       = m._valueType;
911   _interlacingType = m._interlacingType;
912   //drivers = m._drivers;
913 }
914
915 /*!
916   \if developper
917   Not implemented.
918   \endif
919 */
920 template <class T, class INTERLACING_TAG>
921 FIELD<T, INTERLACING_TAG> & FIELD<T, INTERLACING_TAG>::operator=(const FIELD &m)
922 {
923   MESSAGE("Appel de FIELD<T>::operator=") ;
924   if ( this == &m) return *this;
925
926   // copy values array
927   FIELD_::operator=(m);  // Driver are ignored & ?copie su pointeur de Support?
928
929   _value           = m._value; //PROBLEME RECOPIE DES POINTEURS PAS COHERENT AVEC LE
930                                //CONSTRUCTEUR PAR RECOPIE
931                                //CF :Commentaire dans MEDMEM_Array
932   locMap::const_iterator it;
933   for ( it = m._gaussModel.begin();it != m._gaussModel.end(); it++ )
934     _gaussModel[dynamic_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ((*it).second)->getType()]=
935       new GAUSS_LOCALIZATION<INTERLACING_TAG>(
936                                               *dynamic_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ( (*it).second )
937                                               );
938
939   _valueType       = m._valueType;
940   _interlacingType = m._interlacingType;
941
942   return *this;
943 }
944
945 /*!
946      Overload addition operator.
947      This operation is authorized only for compatible fields that have the same support.
948      The compatibility checking includes equality tests of the folowing data members:\n
949      - _support
950      - _numberOfComponents
951      - _numberOfValues
952      - _componentsTypes
953      - _MEDComponentsUnits.
954
955      The data members of the returned field are initialized, based on the first field, except for the name,
956      which is the combination of the two field's names and the operator.
957      Advised Utilisation in C++ : <tt> FIELD<T> c = a + b; </tt> \n
958      In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
959      When using python, this operator calls the copy constructor in any case.
960      The user has to be aware that when using operator + in associatives expressions like
961      <tt> a = b + c + d +e; </tt> \n
962      no optimisation is performed : the evaluation of last expression requires the construction of
963      3 temporary fields.
964 */
965 template <class T, class INTERLACING_TAG>
966 const FIELD<T, INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::operator+(const FIELD & m) const
967 {
968     BEGIN_OF("FIELD<T>::operator+(const FIELD & m)");
969     FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
970
971     // Creation of the result - memory is allocated by FIELD constructor
972     FIELD<T, INTERLACING_TAG> result(this->getSupport(),this->getNumberOfComponents());
973     //result._operation(*this,m,mode,"+"); // perform Atribute's initialization & addition
974     result._operationInitialize(*this,m,"+"); // perform Atribute's initialization
975     result._add_in_place(*this,m); // perform addition
976
977     END_OF("FIELD<T>::operator+(const FIELD & m)");
978     return result;
979 }
980
981 /*!  Overloaded Operator +=
982  *   Operations are directly performed in the first field's array.
983  *   This operation is authorized only for compatible fields that have the same support.
984  */
985 template <class T, class INTERLACING_TAG>
986 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator+=(const FIELD & m)
987 {
988     BEGIN_OF("FIELD<T>::operator+=(const FIELD & m)");
989     FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
990
991     const T* value1=m.getValue(); // get pointers to the values we are adding
992
993     // get a non const pointer to the inside array of values and perform operation
994     T * value=const_cast<T *> (getValue());
995     const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
996     const T* endV=value+size; // pointer to the end of value
997     for(;value!=endV; value1++,value++)
998         *value += *value1;
999     END_OF("FIELD<T>::operator+=(const FIELD & m)");
1000     return *this;
1001 }
1002
1003
1004 /*! Addition of fields. Static member function.
1005  *  The function return a pointer to a new created field that holds the addition.
1006  *  Data members are checked for compatibility and initialized.
1007  *  The user is in charge of memory deallocation.
1008  */
1009 template <class T, class INTERLACING_TAG>
1010 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::add(const FIELD& m, const FIELD& n)
1011 {
1012     BEGIN_OF("FIELD<T>::add(const FIELD & m, const FIELD& n)");
1013     FIELD_::_checkFieldCompatibility(m, n); // may throw exception
1014
1015     // Creation of a new field
1016     FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1017                                                                       m.getNumberOfComponents());
1018     result->_operationInitialize(m,n,"+"); // perform Atribute's initialization
1019     result->_add_in_place(m,n); // perform addition
1020
1021     END_OF("FIELD<T>::add(const FIELD & m, const FIELD& n)");
1022     return result;
1023 }
1024
1025 /*! Same as add method except that field check is deeper.
1026  */
1027 template <class T, class INTERLACING_TAG>
1028 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::addDeep(const FIELD& m, const FIELD& n)
1029 {
1030     BEGIN_OF("FIELD<T>::addDeep(const FIELD & m, const FIELD& n)");
1031     FIELD_::_deepCheckFieldCompatibility(m, n); // may throw exception
1032
1033     // Creation of a new field
1034     FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1035                                                                       m.getNumberOfComponents());
1036     result->_operationInitialize(m,n,"+"); // perform Atribute's initialization
1037     result->_add_in_place(m,n); // perform addition
1038
1039     END_OF("FIELD<T>::addDeep(const FIELD & m, const FIELD& n)");
1040     return result;
1041 }
1042
1043 /*!
1044      Overload substraction operator.
1045      This operation is authorized only for compatible fields that have the same support.
1046      The compatibility checking includes equality tests of the folowing data members:\n
1047      - _support
1048      - _numberOfComponents
1049      - _numberOfValues
1050      - _componentsTypes
1051      - _MEDComponentsUnits.
1052
1053      The data members of the returned field are initialized, based on the first field, except for the name,
1054      which is the combination of the two field's names and the operator.
1055      Advised Utilisation in C++ : <tt> FIELD<T> c = a - b; </tt> \n
1056      In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1057      When using python, this operator calls the copy constructor in any case.
1058      The user has to be aware that when using operator - in associatives expressions like
1059      <tt> a = b - c - d -e; </tt> \n
1060      no optimisation is performed : the evaluation of last expression requires the construction of
1061      3 temporary fields.
1062 */
1063 template <class T, class INTERLACING_TAG>
1064 const FIELD<T, INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::operator-(const FIELD & m) const
1065 {
1066     BEGIN_OF("FIELD<T>::operator-(const FIELD & m)");
1067     FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1068
1069     // Creation of the result - memory is allocated by FIELD constructor
1070     FIELD<T, INTERLACING_TAG> result(this->getSupport(),this->getNumberOfComponents());
1071     //result._operation(*this,m,mode,"-"); // perform Atribute's initialization & substraction
1072     result._operationInitialize(*this,m,"-"); // perform Atribute's initialization
1073     result._sub_in_place(*this,m); // perform substracion
1074
1075     END_OF("FIELD<T>::operator-(const FIELD & m)");
1076     return result;
1077 }
1078
1079 template <class T, class INTERLACING_TAG>
1080 const FIELD<T, INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::operator-() const
1081 {
1082     BEGIN_OF("FIELD<T>::operator-()");
1083
1084     // Creation of the result - memory is allocated by FIELD constructor
1085     FIELD<T, INTERLACING_TAG> result(this->getSupport(),this->getNumberOfComponents());
1086     // Atribute's initialization
1087     result.setName("- "+getName());
1088     result.setComponentsNames(getComponentsNames());
1089     // not yet implemented    setComponentType(getComponentType());
1090     result.setComponentsDescriptions(getComponentsDescriptions());
1091     result.setMEDComponentsUnits(getMEDComponentsUnits());
1092     result.setComponentsUnits(getComponentsUnits());
1093     result.setIterationNumber(getIterationNumber());
1094     result.setTime(getTime());
1095     result.setOrderNumber(getOrderNumber());
1096
1097     const T* value1=getValue();
1098     // get a non const pointer to the inside array of values and perform operation
1099     T * value=const_cast<T *> (result.getValue());
1100     const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1101     const T* endV=value+size; // pointer to the end of value
1102
1103     for(;value!=endV; value1++,value++)
1104         *value = -(*value1);
1105     END_OF("FIELD<T>::operator-=(const FIELD & m)");
1106     return result;
1107 }
1108
1109 /*!  Overloaded Operator -=
1110  *   Operations are directly performed in the first field's array.
1111  *   This operation is authorized only for compatible fields that have the same support.
1112  */
1113 template <class T, class INTERLACING_TAG>
1114 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator-=(const FIELD & m)
1115 {
1116     BEGIN_OF("FIELD<T>::operator-=(const FIELD & m)");
1117     FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1118
1119     const T* value1=m.getValue();
1120
1121     // get a non const pointer to the inside array of values and perform operation
1122     T * value=const_cast<T *> (getValue());
1123     const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1124     const T* endV=value+size; // pointer to the end of value
1125
1126     for(;value!=endV; value1++,value++)
1127         *value -= *value1;
1128
1129     END_OF("FIELD<T>::operator-=(const FIELD & m)");
1130     return *this;
1131 }
1132
1133
1134 /*! Substraction of fields. Static member function.
1135  *  The function return a pointer to a new created field that holds the substraction.
1136  *  Data members are checked for compatibility and initialized.
1137  *  The user is in charge of memory deallocation.
1138  */
1139 template <class T, class INTERLACING_TAG>
1140 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::sub(const FIELD& m, const FIELD& n)
1141 {
1142     BEGIN_OF("FIELD<T>::sub(const FIELD & m, const FIELD& n)");
1143     FIELD_::_checkFieldCompatibility(m, n); // may throw exception
1144
1145     // Creation of a new field
1146     FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1147                                                                       m.getNumberOfComponents());
1148     result->_operationInitialize(m,n,"-"); // perform Atribute's initialization
1149     result->_sub_in_place(m,n); // perform substraction
1150
1151     END_OF("FIELD<T>::sub(const FIELD & m, const FIELD& n)");
1152     return result;
1153 }
1154
1155 /*! Same as sub method except that field check is deeper.
1156  */
1157 template <class T, class INTERLACING_TAG>
1158 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::subDeep(const FIELD& m, const FIELD& n)
1159 {
1160     BEGIN_OF("FIELD<T>::subDeep(const FIELD & m, const FIELD& n)");
1161     FIELD_::_deepCheckFieldCompatibility(m, n); // may throw exception
1162
1163     // Creation of a new field
1164     FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1165                                                                       m.getNumberOfComponents());
1166     result->_operationInitialize(m,n,"-"); // perform Atribute's initialization
1167     result->_sub_in_place(m,n); // perform substraction
1168
1169     END_OF("FIELD<T>::subDeep(const FIELD & m, const FIELD& n)");
1170     return result;
1171 }
1172
1173 /*!
1174      Overload multiplication operator.
1175      This operation is authorized only for compatible fields that have the same support.
1176      The compatibility checking includes equality tests of the folowing data members:\n
1177      - _support
1178      - _numberOfComponents
1179      - _numberOfValues
1180      - _componentsTypes
1181      - _MEDComponentsUnits.
1182
1183      The data members of the returned field are initialized, based on the first field, except for the name,
1184      which is the combination of the two field's names and the operator.
1185      Advised Utilisation in C++ : <tt> FIELD<T> c = a * b; </tt> \n
1186      In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1187      When using python, this operator calls the copy constructor in any case.
1188      The user has to be aware that when using operator * in associatives expressions like
1189      <tt> a = b * c * d *e; </tt> \n
1190      no optimisation is performed : the evaluation of last expression requires the construction of
1191      3 temporary fields.
1192 */
1193 template <class T, class INTERLACING_TAG>
1194 const FIELD<T, INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::operator*(const FIELD & m) const
1195 {
1196     BEGIN_OF("FIELD<T>::operator*(const FIELD & m)");
1197     FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1198
1199     // Creation of the result - memory is allocated by FIELD constructor
1200     FIELD<T, INTERLACING_TAG> result(this->getSupport(),this->getNumberOfComponents());
1201     //result._operation(*this,m,mode,"*"); // perform Atribute's initialization & multiplication
1202     result._operationInitialize(*this,m,"*"); // perform Atribute's initialization
1203     result._mul_in_place(*this,m); // perform multiplication
1204
1205     END_OF("FIELD<T>::operator*(const FIELD & m)");
1206     return result;
1207 }
1208
1209 /*!  Overloaded Operator *=
1210  *   Operations are directly performed in the first field's array.
1211  *   This operation is authorized only for compatible fields that have the same support.
1212  */
1213 template <class T, class INTERLACING_TAG>
1214 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator*=(const FIELD & m)
1215 {
1216     BEGIN_OF("FIELD<T>::operator*=(const FIELD & m)");
1217     FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1218
1219     const T* value1=m.getValue();
1220
1221     // get a non const pointer to the inside array of values and perform operation
1222     T * value=const_cast<T *> (getValue());
1223     const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1224     const T* endV=value+size; // pointer to the end of value
1225
1226     for(;value!=endV; value1++,value++)
1227         *value *= *value1;
1228
1229     END_OF("FIELD<T>::operator*=(const FIELD & m)");
1230     return *this;
1231 }
1232
1233
1234 /*! Multiplication of fields. Static member function.
1235  *  The function return a pointer to a new created field that holds the multiplication.
1236  *  Data members are checked for compatibility and initialized.
1237  *  The user is in charge of memory deallocation.
1238  */
1239 template <class T, class INTERLACING_TAG>
1240 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::mul(const FIELD& m, const FIELD& n)
1241 {
1242     BEGIN_OF("FIELD<T>::mul(const FIELD & m, const FIELD& n)");
1243     FIELD_::_checkFieldCompatibility(m, n, false); // may throw exception
1244
1245     // Creation of a new field
1246     FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1247                                                                       m.getNumberOfComponents());
1248     result->_operationInitialize(m,n,"*"); // perform Atribute's initialization
1249     result->_mul_in_place(m,n); // perform multiplication
1250
1251     END_OF("FIELD<T>::mul(const FIELD & m, const FIELD& n)");
1252     return result;
1253 }
1254
1255 /*! Same as mul method except that field check is deeper.
1256  */
1257 template <class T, class INTERLACING_TAG>
1258 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::mulDeep(const FIELD& m, const FIELD& n)
1259 {
1260     BEGIN_OF("FIELD<T>::mulDeep(const FIELD & m, const FIELD& n)");
1261     FIELD_::_deepCheckFieldCompatibility(m, n, false); // may throw exception
1262
1263     // Creation of a new field
1264     FIELD<T, INTERLACING_TAG>* result = new FIELD<T,INTERLACING_TAG>(m.getSupport(),
1265                                                                      m.getNumberOfComponents());
1266     result->_operationInitialize(m,n,"*"); // perform Atribute's initialization
1267     result->_mul_in_place(m,n); // perform multiplication
1268
1269     END_OF("FIELD<T>::mulDeep(const FIELD & m, const FIELD& n)");
1270     return result;
1271 }
1272
1273 /*!
1274      Overload division operator.
1275      This operation is authorized only for compatible fields that have the same support.
1276      The compatibility checking includes equality tests of the folowing data members:\n
1277      - _support
1278      - _numberOfComponents
1279      - _numberOfValues
1280      - _componentsTypes
1281      - _MEDComponentsUnits.
1282
1283      The data members of the returned field are initialized, based on the first field, except for the name,
1284      which is the combination of the two field's names and the operator.
1285      Advised Utilisation in C++ : <tt> FIELD<T> c = a / b; </tt> \n
1286      In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1287      When using python, this operator calls the copy constructor in any case.
1288      The user has to be aware that when using operator / in associatives expressions like
1289      <tt> a = b / c / d /e; </tt> \n
1290      no optimisation is performed : the evaluation of last expression requires the construction of
1291      3 temporary fields.
1292 */
1293 template <class T, class INTERLACING_TAG>
1294 const FIELD<T, INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::operator/(const FIELD & m) const
1295 {
1296     BEGIN_OF("FIELD<T>::operator/(const FIELD & m)");
1297     FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1298
1299     // Creation of the result - memory is allocated by FIELD constructor
1300     FIELD<T, INTERLACING_TAG> result(this->getSupport(),this->getNumberOfComponents());
1301     //result._operation(*this,m,mode,"/"); // perform Atribute's initialization & division
1302     result._operationInitialize(*this,m,"/"); // perform Atribute's initialization
1303     result._div_in_place(*this,m); // perform division
1304
1305     END_OF("FIELD<T>::operator/(const FIELD & m)");
1306     return result;
1307 }
1308
1309
1310 /*!  Overloaded Operator /=
1311  *   Operations are directly performed in the first field's array.
1312  *   This operation is authorized only for compatible fields that have the same support.
1313  */
1314 template <class T, class INTERLACING_TAG>
1315 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator/=(const FIELD & m)
1316 {
1317     BEGIN_OF("FIELD<T>::operator/=(const FIELD & m)");
1318     FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1319
1320     const T* value1=m.getValue(); // get pointers to the values we are adding
1321
1322     // get a non const pointer to the inside array of values and perform operation
1323     T * value=const_cast<T *> (getValue());
1324     const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1325     const T* endV=value+size; // pointer to the end of value
1326
1327     for(;value!=endV; value1++,value++)
1328         *value /= *value1;
1329
1330     END_OF("FIELD<T>::operator/=(const FIELD & m)");
1331     return *this;
1332 }
1333
1334
1335 /*! Division of fields. Static member function.
1336  *  The function return a pointer to a new created field that holds the division.
1337  *  Data members are checked for compatibility and initialized.
1338  *  The user is in charge of memory deallocation.
1339  */
1340 template <class T, class INTERLACING_TAG>
1341 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::div(const FIELD& m, const FIELD& n)
1342 {
1343     BEGIN_OF("FIELD<T>::div(const FIELD & m, const FIELD& n)");
1344     FIELD_::_checkFieldCompatibility(m, n, false); // may throw exception
1345
1346     // Creation of a new field
1347     FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1348                                                                       m.getNumberOfComponents());
1349     result->_operationInitialize(m,n,"/"); // perform Atribute's initialization
1350     result->_div_in_place(m,n); // perform division
1351
1352     END_OF("FIELD<T>::div(const FIELD & m, const FIELD& n)");
1353     return result;
1354 }
1355
1356 /*! Same as div method except that field check is deeper.
1357  */
1358 template <class T,class INTERLACING_TAG>
1359 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::divDeep(const FIELD& m, const FIELD& n)
1360 {
1361   BEGIN_OF("FIELD<T>::divDeep(const FIELD & m, const FIELD& n)");
1362   FIELD_::_deepCheckFieldCompatibility(m, n, false); // may throw exception
1363
1364   // Creation of a new field
1365   FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1366                                                                     m.getNumberOfComponents());
1367   result->_operationInitialize(m,n,"/"); // perform Atribute's initialization
1368   result->_div_in_place(m,n); // perform division
1369
1370   END_OF("FIELD<T>::divDeep(const FIELD & m, const FIELD& n)");
1371   return result;
1372 }
1373
1374 /*!
1375   \if developper
1376   This internal method initialize the members of a new field created to hold the result of the operation Op .
1377   Initialization is based on the first field, except for the name, which is the combination of the two field's names
1378   and the operator.
1379   \endif
1380 */
1381 template <class T, class INTERLACING_TAG>
1382 void FIELD<T, INTERLACING_TAG>::_operationInitialize(const FIELD& m,const FIELD& n, char* Op)
1383 {
1384     MESSAGE("Appel methode interne " << Op);
1385
1386     // Atribute's initialization (copy of the first field's attributes)
1387     // Other data members (_support, _numberOfValues) are initialized in the field's constr.
1388     setName(m.getName()+" "+Op+" "+n.getName());
1389     setComponentsNames(m.getComponentsNames());
1390     // not yet implemented    setComponentType(m.getComponentType());
1391     setComponentsDescriptions(m.getComponentsDescriptions());
1392     setMEDComponentsUnits(m.getMEDComponentsUnits());
1393
1394     // The following data member may differ from field m to n.
1395     // The initialization is done based on the first field.
1396
1397     if(m.getComponentsUnits() != NULL)
1398       setComponentsUnits(m.getComponentsUnits());
1399     else
1400       _componentsUnits = (UNIT *) NULL;
1401
1402     setIterationNumber(m.getIterationNumber());
1403     setTime(m.getTime());
1404     setOrderNumber(m.getOrderNumber());
1405 }
1406
1407
1408 /*!
1409   \if developper
1410   Internal method called by FIELD<T>::operator+ and FIELD<T>::add to perform addition "in place".
1411   This method is applied to a just created field with medModeSwitch mode.
1412   For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1413   it doesn't exist!
1414   \endif
1415 */
1416 template <class T, class INTERLACING_TAG>
1417 void FIELD<T, INTERLACING_TAG>::_add_in_place(const FIELD& m,const FIELD& n)
1418 {
1419     // get pointers to the values we are adding
1420     const T* value1=m.getValue();
1421     const T* value2=n.getValue();
1422     // get a non const pointer to the inside array of values and perform operation
1423     T * value=const_cast<T *> (getValue());
1424
1425     const int size=getNumberOfValues()*getNumberOfComponents();
1426     SCRUTE(size);
1427     const T* endV1=value1+size;
1428     for(;value1!=endV1; value1++,value2++,value++)
1429         *value=(*value1)+(*value2);
1430 }
1431
1432 /*!
1433   \if developper
1434   Internal method called by FIELD<T>::operator- and FIELD<T>::sub to perform substraction "in place".
1435   This method is applied to a just created field with medModeSwitch mode.
1436   For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1437   it doesn't exist!
1438   \endif
1439 */
1440 template <class T, class INTERLACING_TAG>
1441 void FIELD<T, INTERLACING_TAG>::_sub_in_place(const FIELD& m,const FIELD& n)
1442 {
1443     // get pointers to the values we are adding
1444     const T* value1=m.getValue();
1445     const T* value2=n.getValue();
1446     // get a non const pointer to the inside array of values and perform operation
1447     T * value=const_cast<T *> (getValue());
1448
1449     const int size=getNumberOfValues()*getNumberOfComponents();
1450     SCRUTE(size);
1451     const T* endV1=value1+size;
1452     for(;value1!=endV1; value1++,value2++,value++)
1453         *value=(*value1)-(*value2);
1454 }
1455
1456 /*!
1457   \if developper
1458   Internal method called by FIELD<T>::operator* and FIELD<T>::mul to perform multiplication "in place".
1459   This method is applied to a just created field with medModeSwitch mode.
1460   For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1461   it doesn't exist!
1462   \endif
1463 */
1464 template <class T, class INTERLACING_TAG>
1465 void FIELD<T, INTERLACING_TAG>::_mul_in_place(const FIELD& m,const FIELD& n)
1466 {
1467     // get pointers to the values we are adding
1468     const T* value1=m.getValue();
1469     const T* value2=n.getValue();
1470     // get a non const pointer to the inside array of values and perform operation
1471     T * value=const_cast<T *> (getValue());
1472
1473     const int size=getNumberOfValues()*getNumberOfComponents();
1474     SCRUTE(size);
1475     const T* endV1=value1+size;
1476     for(;value1!=endV1; value1++,value2++,value++)
1477         *value=(*value1)*(*value2);
1478 }
1479
1480 /*!
1481   \if developper
1482   Internal method called by FIELD<T>::operator/ and FIELD<T>::div to perform division "in place".
1483   This method is applied to a just created field with medModeSwitch mode.
1484   For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1485   it doesn't exist!
1486   \endif
1487 */
1488 template <class T, class INTERLACING_TAG>
1489 void FIELD<T, INTERLACING_TAG>::_div_in_place(const FIELD& m,const FIELD& n) throw (MEDEXCEPTION)
1490 {
1491     // get pointers to the values we are adding
1492     const T* value1=m.getValue();
1493     const T* value2=n.getValue();
1494     // get a non const pointer to the inside array of values and perform operation
1495     T * value=const_cast<T *> (getValue());
1496
1497     const int size=getNumberOfValues()*getNumberOfComponents();
1498     SCRUTE(size);
1499     const T* endV1=value1+size;
1500     for(;value1!=endV1; value1++,value2++,value++){
1501       if ( *value2 == 0 ) { // FAIRE PLUTOT UN TRY CATCH Rmq from EF
1502           string diagnosis;
1503           diagnosis="FIELD<T,INTERLACING_TAG>::_div_in_place(...) : Divide by zero !";
1504           throw MEDEXCEPTION(diagnosis.c_str());
1505         }
1506         *value=(*value1)/(*value2);
1507     }
1508 }
1509
1510 /*!  Return Max Norm
1511  */
1512 template <class T, class INTERLACIN_TAG> double FIELD<T, INTERLACIN_TAG>::normMax() const throw (MEDEXCEPTION)
1513 {
1514     const T* value=getValue(); // get pointer to the values
1515     const int size=getNumberOfValues()*getNumberOfComponents();
1516     if (size <= 0) // Size of array has to be strictly positive
1517     {
1518         string diagnosis;
1519         diagnosis="FIELD<T,INTERLACIN_TAG>::normMax() : cannot compute the norm of "+getName()+
1520             " : it size is non positive!";
1521         throw MEDEXCEPTION(diagnosis.c_str());
1522     }
1523     const T* lastvalue=value+size; // get pointer just after last value
1524     const T* pMax=value; // pointer to the max value
1525     const T* pMin=value; // pointer to the min value
1526
1527     // get pointers to the max & min value of array
1528     while ( ++value != lastvalue )
1529     {
1530         if ( *pMin > *value )
1531             pMin=value;
1532         if ( *pMax < *value )
1533             pMax=value;
1534     }
1535
1536     T Max= *pMax>(T) 0 ? *pMax : -*pMax; // Max=abs(*pMax)
1537     T Min= *pMin>(T) 0 ? *pMin : -*pMin; // Min=abs(*pMin)
1538
1539     return Max>Min ? static_cast<double>(Max) : static_cast<double>(Min);
1540 }
1541
1542 /*!  Return Euclidien norm
1543  */
1544 template <class T, class INTERLACIN_TAG> double FIELD<T, INTERLACIN_TAG>::norm2() const throw (MEDEXCEPTION)
1545 {
1546     const T* value=this->getValue(); // get const pointer to the values
1547     const int size=getNumberOfValues()*getNumberOfComponents(); // get size of array
1548     if (size <= 0) // Size of array has to be strictly positive
1549     {
1550         string diagnosis;
1551         diagnosis="FIELD<T,INTERLACIN_TAG>::norm2() : cannot compute the norm of "+getName()+
1552             " : it size is non positive!";
1553         throw MEDEXCEPTION(diagnosis.c_str());
1554     }
1555     const T* lastvalue=value+size; // point just after last value
1556
1557     T result((T)0); // init
1558     for( ; value!=lastvalue ; ++value)
1559         result += (*value) * (*value);
1560
1561     return std::sqrt(static_cast<double> (result));
1562 }
1563
1564
1565 /*!  Apply to each (scalar) field component the template parameter T_function,
1566  *   which is a pointer to function.
1567  *   Since the pointer is known at compile time, the function is inlined into the inner loop!
1568  *   calculation is done "in place".
1569  *   Use examples :
1570  *
1571  *   \code  myField.applyFunc<std::sqrt>();  // apply sqare root function \endcode
1572  *     \code myField.applyFunc<myFunction>(); // apply your own created function \endcode
1573  */
1574 template <class T, class INTERLACIN_TAG> template <T T_function(T)>
1575 void FIELD<T, INTERLACIN_TAG>::applyFunc()
1576 {
1577   // get a non const pointer to the inside array of values and perform operation
1578     T * value=const_cast<T *> (getValue());
1579     const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1580
1581     if (size>0) // for a negative size, there is nothing to do
1582     {
1583         const T* lastvalue=value+size; // pointer to the end of value
1584         for(;value!=lastvalue; ++value) // apply linear transformation
1585             *value = T_function(*value);
1586     }
1587 }
1588
1589 template <class T, class INTERLACIN_TAG> T FIELD<T, INTERLACIN_TAG>::pow(T x)
1590 {
1591   return (T)::pow(x,FIELD<T, INTERLACIN_TAG>::_scalarForPow);
1592 }
1593
1594 /*!  Apply to each (scalar) field component the math function pow.
1595  *   calculation is done "in place".
1596  *   Use examples :
1597  *
1598  *   \code  myField.applyFunc<std::sqrt>();  // apply sqare root function \endcode
1599  *     \code myField.applyFunc<myFunction>(); // apply your own created function \endcode
1600  */
1601 template <class T, class INTERLACIN_TAG> void FIELD<T, INTERLACIN_TAG>::applyPow(T scalar)
1602 {
1603   FIELD<T, INTERLACIN_TAG>::_scalarForPow=scalar;
1604   applyFunc<FIELD<T, INTERLACIN_TAG>::pow>();
1605 }
1606
1607 /*!  Apply to each (scalar) field component the linear function x -> ax+b.
1608  *   calculation is done "in place".
1609  */
1610 template <class T, class INTERLACIN_TAG> void FIELD<T, INTERLACIN_TAG>::applyLin(T a, T b)
1611 {
1612     // get a non const pointer to the inside array of values and perform operation in place
1613     T * value=const_cast<T *> (getValue());
1614     const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1615
1616     if (size>0) // for a negative size, there is nothing to do
1617     {
1618         const T* lastvalue=value+size; // pointer to the end of value
1619         for(;value!=lastvalue; ++value) // apply linear transformation
1620             *value = a*(*value)+b;
1621     }
1622 }
1623
1624
1625 /*!
1626  *   Return a pointer to a new field that holds the scalar product. Static member function.
1627  *   This operation is authorized only for compatible fields that have the same support.
1628  *   The compatibility checking includes equality tests of the folowing data members:\n
1629  *   - _support
1630  *   - _numberOfComponents
1631  *   - _numberOfValues
1632  *   - _componentsTypes
1633  *   - _MEDComponentsUnits.
1634  *   Data members are initialized.
1635  *   The new field point to the same support and has one component.
1636  *   Each value of it is the scalar product of the two argument's fields.
1637  *   The user is in charge of memory deallocation.
1638  */
1639 template <class T, class INTERLACING_TAG>
1640 FIELD<T, INTERLACING_TAG>*
1641 FIELD<T, INTERLACING_TAG>::scalarProduct(const FIELD & m, const FIELD & n, bool deepCheck)
1642 {
1643     if(!deepCheck)
1644       FIELD_::_checkFieldCompatibility( m, n, false); // may throw exception
1645     else
1646       FIELD_::_deepCheckFieldCompatibility(m, n, false);
1647
1648     // we need a MED_FULL_INTERLACE representation of m & n to compute the scalar product
1649     // result type imply INTERLACING_TAG=FullInterlace for m & n
1650
1651     const int numberOfElements=m.getNumberOfValues(); // strictly positive
1652     const int NumberOfComponents=m.getNumberOfComponents(); // strictly positive
1653
1654     // Creation & init of a the result field on the same support, with one component
1655     // You have to be careful about the interlacing mode, because in the computation step,
1656     // it seems to assume the the interlacing mode is the FullInterlacing
1657
1658     FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),1);
1659     result->setName( "scalarProduct ( " + m.getName() + " , " + n.getName() + " )" );
1660     result->setIterationNumber(m.getIterationNumber());
1661     result->setTime(m.getTime());
1662     result->setOrderNumber(m.getOrderNumber());
1663
1664     const T* value1=m.getValue(); // get const pointer to the values
1665     const T* value2=n.getValue(); // get const pointer to the values
1666     // get a non const pointer to the inside array of values and perform operation
1667     T * value=const_cast<T *> (result->getValue());
1668
1669     const T* lastvalue=value+numberOfElements; // pointing just after last value of result
1670     for ( ; value!=lastvalue ; ++value ) // loop on all elements
1671     {
1672         *value=(T)0; // initialize value
1673         const T* endofRow=value1+NumberOfComponents; // pointing just after end of row
1674         for ( ; value1 != endofRow; ++value1, ++value2) // computation of dot product
1675             *value += (*value1) * (*value2);
1676     }
1677     return result;
1678 }
1679
1680 /*!  Return L2 Norm  of the field's component.
1681  *   Cannot be applied to a field with a support on nodes.
1682  *   If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1683  */
1684 template <class T, class INTERLACING_TAG>
1685 double FIELD<T, INTERLACING_TAG>::normL2(int component,
1686                                          const FIELD<double, FullInterlace> * p_field_volume) const
1687 {
1688     _checkNormCompatibility(p_field_volume); // may throw exception
1689     if ( component<1 || component>getNumberOfComponents() )
1690         throw MEDEXCEPTION(STRING("FIELD<T>::normL2() : The component argument should be between 1 and the number of components"));
1691
1692     const FIELD<double, FullInterlace> * p_field_size=p_field_volume;
1693     if(!p_field_volume) // if the user don't supply the volume
1694         p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1695
1696     // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1697     const double* vol=p_field_size->getValue();
1698     // Il n'est vraiment pas optimal de mixer des champs dans des modes d'entrelacement
1699     // different juste pour le calcul
1700
1701     const T * value     = NULL;
1702     ArrayNo * myArray   = NULL;
1703     if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
1704       value = getValue();
1705     else {
1706       myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
1707       value   = myArray->getPtr();
1708     }
1709
1710     const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column
1711
1712     double integrale=0.0;
1713     double totVol=0.0;
1714     for (; value!=lastvalue ; ++value ,++vol)
1715     {
1716         integrale += static_cast<double>((*value) * (*value)) * (*vol);
1717         totVol+=*vol;
1718     }
1719
1720     if(!p_field_volume) // if the user didn't supply the volume
1721         delete p_field_size; // delete temporary volume field
1722     if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
1723     if( totVol <= 0)
1724         throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1725
1726     return integrale/totVol;
1727 }
1728
1729 /*!  Return L2 Norm  of the field.
1730  *   Cannot be applied to a field with a support on nodes.
1731  *   If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1732  */
1733 template <class T, class INTERLACING_TAG>
1734 double FIELD<T, INTERLACING_TAG>::normL2(const FIELD<double, FullInterlace> * p_field_volume) const
1735 {
1736     _checkNormCompatibility(p_field_volume); // may throw exception
1737     const FIELD<double, FullInterlace> * p_field_size=p_field_volume;
1738     if(!p_field_volume) // if the user don't supply the volume
1739         p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1740
1741     // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1742     const double* vol=p_field_size->getValue();
1743     const double* lastvol=vol+getNumberOfValues(); // pointing just after the end of vol
1744
1745     const T * value     = NULL;
1746     ArrayNo * myArray   = NULL;
1747     if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
1748       value = getValue();
1749     else {
1750       myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
1751       value   = myArray->getPtr();
1752     }
1753
1754     double totVol=0.0;
1755     const double* p_vol=vol;
1756     for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume
1757         totVol+=*p_vol;
1758
1759     double integrale=0.0;
1760     for (int i=1; i<=getNumberOfComponents(); ++i) // compute integral on all components
1761         for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol)
1762             integrale += static_cast<double>((*value) * (*value)) * (*p_vol);
1763
1764     if(!p_field_volume) // if the user didn't supply the volume
1765         delete p_field_size; // delete temporary volume field
1766     if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
1767     if( totVol <= 0)
1768         throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1769
1770     return integrale/totVol;
1771 }
1772
1773 /*!  Return L1 Norm  of the field's component.
1774  *   Cannot be applied to a field with a support on nodes.
1775  *   If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1776  */
1777 template <class T, class INTERLACING_TAG>
1778 double FIELD<T, INTERLACING_TAG>::normL1(int component,
1779                                          const FIELD<double, FullInterlace > * p_field_volume) const
1780 {
1781     _checkNormCompatibility(p_field_volume); // may throw exception
1782     if ( component<1 || component>getNumberOfComponents() )
1783         throw MEDEXCEPTION(STRING("FIELD<T,INTERLACING_TAG>::normL2() : The component argument should be between 1 and the number of components"));
1784
1785     const FIELD<double,FullInterlace> * p_field_size=p_field_volume;
1786     if(!p_field_volume) // if the user don't supply the volume
1787         p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1788
1789     // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1790     const double* vol=p_field_size->getValue();
1791     const T * value     = NULL;
1792     ArrayNo * myArray   = NULL;
1793     if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
1794       value = getColumn(component);
1795     else {
1796       myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
1797       value   = myArray->getColumn(component);
1798     }
1799
1800     const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column
1801
1802     double integrale=0.0;
1803     double totVol=0.0;
1804     for (; value!=lastvalue ; ++value ,++vol)
1805     {
1806         integrale += std::abs( static_cast<double>(*value) ) * (*vol);
1807         totVol+=*vol;
1808     }
1809
1810     if(!p_field_volume) // if the user didn't supply the volume
1811         delete p_field_size; // delete temporary volume field
1812     if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
1813     if( totVol <= 0)
1814         throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1815
1816     return integrale/totVol;
1817 }
1818
1819 /*!  Return L1 Norm  of the field.
1820  *   Cannot be applied to a field with a support on nodes.
1821  *   If the optional p_field_volume argument is furnished, the volume is not re-calculated.
1822  */
1823 template <class T, class INTERLACING_TAG>
1824 double FIELD<T, INTERLACING_TAG>::normL1(const FIELD<double, FullInterlace> * p_field_volume) const
1825 {
1826     _checkNormCompatibility(p_field_volume); // may throw exception
1827     const FIELD<double, FullInterlace> * p_field_size=p_field_volume;
1828     if(!p_field_volume) // if the user don't supply the volume
1829         p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
1830
1831     // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
1832     const double* vol=p_field_size->getValue();
1833     const double* lastvol=vol+getNumberOfValues(); // pointing just after the end of vol
1834
1835    const T * value     = NULL;
1836     ArrayNo * myArray   = NULL;
1837     if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
1838       value = getValue();
1839     else {
1840       myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
1841       value   = myArray->getPtr();
1842     }
1843
1844     double totVol=0.0;
1845     const double* p_vol=vol;
1846     for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume
1847         totVol+=*p_vol;
1848
1849     double integrale=0.0;
1850     for (int i=1; i<=getNumberOfComponents(); ++i) // compute integral on all components
1851         for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol)
1852             integrale += std::abs( static_cast<double>(*value) ) * (*p_vol);
1853
1854     if(!p_field_volume) // if the user didn't supply the volume
1855         delete p_field_size; // delete temporary volume field
1856     if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
1857     if( totVol <= 0)
1858         throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
1859
1860     return integrale/totVol;
1861 }
1862
1863 /*! Return a new field (to deallocate with delete) lying on subSupport that is included by
1864  *   this->_support with corresponding values extracting from this->_value.
1865  */
1866 template <class T, class INTERLACING_TAG>
1867 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION)
1868 {
1869   if(!subSupport->belongsTo(*_support))
1870     throw MEDEXCEPTION("FIELD<T>::extract : subSupport not included in this->_support !");
1871   if(_support->isOnAllElements() && subSupport->isOnAllElements())
1872     return new FIELD<T, INTERLACING_TAG>(*this);
1873
1874   FIELD<T, INTERLACING_TAG> *ret = new FIELD<T, INTERLACING_TAG>(subSupport,
1875                                                                  _numberOfComponents);
1876
1877   if(!ret->_value)
1878     throw MEDEXCEPTION("FIELD<T>::extract : unvalid support detected !");
1879
1880   T* valuesToSet=(T*)ret->getValue();
1881
1882   int nbOfEltsSub=subSupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
1883   const int *eltsSub=subSupport->getNumber(MED_EN::MED_ALL_ELEMENTS);
1884   T* tempVals=new T[_numberOfComponents];
1885   for(int i=0;i<nbOfEltsSub;i++)
1886     {
1887       if(!getValueOnElement(eltsSub[i],tempVals))
1888         throw MEDEXCEPTION("Problem in belongsTo function !!!");
1889       for(int j=0;j<_numberOfComponents;j++)
1890         valuesToSet[i*_numberOfComponents+j]=tempVals[j];
1891     }
1892   delete [] tempVals;
1893
1894   ret->copyGlobalInfo(*this);
1895   return ret;
1896 }
1897
1898 /*!
1899   Constructor with parameters; the object is set via a file and its associated
1900   driver. For the moment only the MED_DRIVER is considered and if the last two
1901   argument (iterationNumber and orderNumber) are not set; their default value
1902   is -1. If the field fieldDriverName with the iteration number
1903   iterationNumber and the order number orderNumber does not exist in the file
1904   fieldDriverName; the constructor raises an exception.
1905 */
1906 template <class T, class INTERLACING_TAG>
1907 FIELD<T, INTERLACING_TAG>::FIELD(const SUPPORT * Support,
1908                                  driverTypes driverType,
1909                                  const string & fileName/*=""*/,
1910                                  const string & fieldDriverName/*=""*/,
1911                                  const int iterationNumber,
1912                                  const int orderNumber) throw (MEDEXCEPTION)
1913 {
1914   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) : ";
1915
1916   int current;
1917
1918   BEGIN_OF(LOC);
1919
1920   init();
1921
1922   //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
1923   ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE)
1924   FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
1925
1926   //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
1927   ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE)
1928   FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
1929
1930   _support = Support;
1931   //A.G. Addings for RC
1932   if(_support)
1933     _support->addReference();
1934   // OCC 10/03/2006 -- According to the rules defined with help of 
1935   // MEDMEM_IntrelacingTraits class, it is not allowed to instantiate
1936   // MEDMEM_Array<> template using INTERLACING_TAG parameter of 
1937   // FIELD template - MSVC++ 2003 compiler generated an error here.
1938   // _value = (MEDMEM_Array<T, INTERLACING_TAG> *) NULL;
1939   _value = NULL;
1940
1941   _iterationNumber = iterationNumber;
1942   _time = 0.0;
1943   _orderNumber = orderNumber;
1944
1945   current = addDriver(driverType,fileName,fieldDriverName,MED_EN::MED_LECT);
1946
1947   _drivers[current]->open();
1948   _drivers[current]->read();
1949   _drivers[current]->close();
1950
1951   END_OF(LOC);
1952 }
1953
1954 /*!
1955   This constructor, at least, allows to create a FIELD without creating any
1956   SUPPORT then without having to load a MESH object, a support is created. It
1957   provides the meshName related mesh but doesn't not set a mesh in the created
1958   support.
1959 */
1960 template <class T, class INTERLACING_TAG>
1961 FIELD<T,INTERLACING_TAG>::FIELD(driverTypes driverType,
1962                                 const string & fileName,
1963                                 const string & fieldDriverName,
1964                                 const int iterationNumber,
1965                                 const int orderNumber)
1966   throw (MEDEXCEPTION) :FIELD_()
1967 {
1968   int current;
1969   const char * LOC ="FIELD<T,INTERLACING_TAG>::FIELD( driverTypes driverType, const string & fileName, string & fieldDriverName, int iterationNumber, int orderNumber) : ";
1970   BEGIN_OF(LOC);
1971
1972   init();
1973
1974   //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
1975   ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE)
1976   FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
1977
1978   //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
1979   ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE)
1980   FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
1981
1982   _support = (SUPPORT *) NULL;
1983   // OCC 10/03/2006 -- According to the rules defined with help of 
1984   // MEDMEM_IntrelacingTraits class, it is not allowed to instantiate
1985   // MEDMEM_Array<> template using INTERLACING_TAG parameter of 
1986   // FIELD template - MSVC++ 2003 compiler generated an error here.
1987   // _value = (MEDMEM_Array<T, INTERLACING_TAG> *) NULL;
1988   _value = NULL;
1989
1990   _iterationNumber = iterationNumber;
1991   _time = 0.0;
1992   _orderNumber = orderNumber;
1993
1994   current = addDriver(driverType,fileName,fieldDriverName,MED_EN::MED_LECT);
1995
1996   _drivers[current]->open();
1997   _drivers[current]->read();
1998   _drivers[current]->close();
1999
2000   END_OF(LOC);
2001 }
2002
2003 /*!
2004   Destructor.
2005 */
2006 template <class T, class INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::~FIELD()
2007 {
2008   BEGIN_OF(" Destructeur FIELD<T, INTERLACING_TAG>::~FIELD()");
2009   SCRUTE(this);
2010   if (_value) delete _value;
2011   locMap::const_iterator it;
2012   for ( it = _gaussModel.begin();it != _gaussModel.end(); it++ )
2013     delete (*it).second;
2014
2015   END_OF(" Destructeur FIELD<T,INTERLACING_TAG>::~FIELD()");
2016 }
2017
2018 /*!
2019
2020 */
2021 template <class T, class INTERLACING_TAG>
2022 void FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents)
2023 {
2024   const char* LOC = "FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents)" ;
2025   BEGIN_OF(LOC);
2026
2027   _numberOfComponents = NumberOfComponents ;
2028   if (_componentsTypes == NULL)
2029     _componentsTypes = new int[NumberOfComponents] ;
2030   if (_componentsNames == NULL)
2031     _componentsNames = new string[NumberOfComponents];
2032   if (_componentsDescriptions == NULL)
2033     _componentsDescriptions = new string[NumberOfComponents];
2034   if (_componentsUnits == NULL)
2035     _componentsUnits = new UNIT[NumberOfComponents];
2036   if (_MEDComponentsUnits == NULL)
2037     _MEDComponentsUnits = new string[NumberOfComponents];
2038   for (int i=0;i<NumberOfComponents;i++) {
2039     _componentsTypes[i] = 0 ;
2040   }
2041
2042   try {
2043     // becarefull about the number of gauss point
2044     _numberOfValues = _support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
2045     MESSAGE(LOC <<" : "<<_numberOfValues <<" et "<< NumberOfComponents);
2046
2047     //EF : A modifier lors de l'intégration de la classe de localisation des points de gauss
2048     _value = new ArrayNoGauss(_numberOfComponents,_numberOfValues);
2049
2050     _isRead = true ;
2051   }
2052   catch (MEDEXCEPTION &ex) {
2053     MESSAGE("No value defined, problem with NumberOfComponents (and may be _support) size of MEDARRAY<T>::_value !");
2054     // OCC 10/03/2006 -- According to the rules defined with help of 
2055     // MEDMEM_IntrelacingTraits class, it is not allowed to instantiate
2056     // MEDMEM_Array<> template using INTERLACING_TAG parameter of 
2057     // FIELD template - MSVC++ 2003 compiler generated an error here.
2058     // _value = (MEDMEM_Array<T, INTERLACING_TAG> *) NULL;
2059     _value = NULL;
2060   }
2061
2062   SCRUTE(_value);
2063   END_OF("void FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents)");
2064 }
2065
2066 /*!
2067
2068 */
2069 template <class T, class INTERLACING_TAG>
2070 void FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents,
2071                                            const int LengthValue)
2072 {
2073   BEGIN_OF("void FIELD<T>::allocValue(const int NumberOfComponents,const int LengthValue)");
2074
2075   _numberOfComponents = NumberOfComponents ;
2076   if (_componentsTypes == NULL)
2077     _componentsTypes = new int[NumberOfComponents] ;
2078   if (_componentsNames == NULL)
2079     _componentsNames = new string[NumberOfComponents];
2080   if (_componentsDescriptions == NULL)
2081     _componentsDescriptions = new string[NumberOfComponents];
2082   if (_componentsUnits == NULL)
2083     _componentsUnits = new UNIT[NumberOfComponents];
2084   if (_MEDComponentsUnits == NULL)
2085     _MEDComponentsUnits = new string[NumberOfComponents];
2086   for (int i=0;i<NumberOfComponents;i++) {
2087     _componentsTypes[i] = 0 ;
2088   }
2089
2090   MESSAGE("FIELD : constructeur : "<<LengthValue <<" et "<< NumberOfComponents);
2091   _numberOfValues = LengthValue ;
2092
2093   //EF : A modifier lors de l'intégration de la classe de localisation des points de gauss
2094   _value = new ArrayNoGauss(_numberOfComponents,_numberOfValues);
2095
2096   _isRead = true ;
2097
2098   SCRUTE(_value);
2099   END_OF("void FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents,const int LengthValue)");
2100 }
2101
2102 /*!
2103
2104 */
2105 template <class T, class INTERLACING_TAG>
2106 void FIELD<T, INTERLACING_TAG>::deallocValue()
2107 {
2108   BEGIN_OF("void FIELD<T, INTERLACING_TAG>::deallocValue()");
2109   _numberOfValues = 0 ;
2110   _numberOfComponents = 0 ;
2111   if (_value != NULL)
2112     delete _value;
2113
2114   END_OF("void FIELD<T, INTERLACING_TAG>::deallocValue()");
2115 }
2116
2117 // -----------------
2118 // Methodes Inline
2119 // -----------------
2120
2121 /*!
2122   Create the specified driver and return its index reference to path to
2123   read or write methods.
2124 */
2125
2126 template <class T, class INTERLACING_TAG>
2127 int FIELD<T, INTERLACING_TAG>::addDriver(driverTypes driverType,
2128                                          const string & fileName/*="Default File Name.med"*/,
2129                                          const string & driverName/*="Default Field Name"*/,
2130                                          MED_EN::med_mode_acces access)
2131 {
2132   //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) : ";
2133   const char * LOC = "FIELD<T>::addDriver(driverTypes driverType, const string & fileName,const string & driverName,MED_EN::med_mode_acces access) :";//jfa tmp
2134
2135   GENDRIVER * driver;
2136
2137   BEGIN_OF(LOC);
2138
2139   SCRUTE(driverType);
2140
2141   driver = DRIVERFACTORY::buildDriverForField(driverType,fileName,this,access);
2142
2143   _drivers.push_back(driver);
2144
2145   int current = _drivers.size()-1;
2146
2147   _drivers[current]->setFieldName(driverName);
2148
2149   END_OF(LOC);
2150
2151   return current;
2152 }
2153
2154
2155 /*!
2156   Duplicate the given driver and return its index reference to path to
2157   read or write methods.
2158 */
2159 template <class T, class INTERLACING_TAG>
2160 inline int FIELD<T, INTERLACING_TAG>::addDriver (GENDRIVER & driver )
2161 {
2162   const char * LOC = "FIELD<T, INTERLACING_TAG>::addDriver(GENDRIVER &) : ";
2163   int current;
2164
2165   BEGIN_OF(LOC);
2166
2167   // duplicate driver to delete it with destructor !
2168   GENDRIVER * newDriver = driver.copy() ;
2169
2170   _drivers.push_back(newDriver);
2171
2172   current = _drivers.size()-1;
2173   SCRUTE(current);
2174   driver.setId(current);
2175
2176   MESSAGE(LOC << " je suis la 1");
2177   END_OF(LOC);
2178   MESSAGE(LOC << " je suis la 2");
2179
2180   return current ;
2181 };
2182
2183 /*!
2184   Remove the driver referenced by its index.
2185 */
2186 template <class T, class INTERLACING_TAG>
2187 void FIELD<T, INTERLACING_TAG>::rmDriver (int index/*=0*/)
2188 {
2189   const char * LOC = "FIELD<T, INTERLACING_TAG>::rmDriver (int index=0): ";
2190   BEGIN_OF(LOC);
2191
2192   if ( _drivers[index] ) {
2193     //_drivers.erase(&_drivers[index]);
2194     // why not ????
2195     MESSAGE ("detruire");
2196   }
2197   else
2198     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
2199                                      << "The <index given is invalid, index must be between  0 and  |"
2200                                      << _drivers.size()
2201                                      )
2202                           );
2203
2204   END_OF(LOC);
2205 }
2206
2207 /*!
2208   Read FIELD in the file specified in the driver given by its index.
2209 */
2210 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::read(int index/*=0*/)
2211 {
2212   const char * LOC = "FIELD<T, INTERLACING_TAG>::read(int index=0) : ";
2213   BEGIN_OF(LOC);
2214
2215   if ( _drivers[index] ) {
2216     _drivers[index]->open();
2217     _drivers[index]->read();
2218     _drivers[index]->close();
2219   }
2220   else
2221     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
2222                                      << "The index given is invalid, index must be between  0 and |"
2223                                      << _drivers.size()
2224                                      )
2225                           );
2226   END_OF(LOC);
2227 }
2228
2229 /*!
2230   Write FIELD in the file specified in the driver given by its index.
2231 */
2232 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::write(int index/*=0*/, const string & driverName /*= ""*/)
2233 {
2234   const char * LOC = "FIELD<T,INTERLACING_TAG>::write(int index=0, const string & driverName = \"\") : ";
2235   BEGIN_OF(LOC);
2236
2237   if( _drivers[index] ) {
2238     _drivers[index]->open();
2239     if (driverName != "") _drivers[index]->setFieldName(driverName);
2240     _drivers[index]->write();
2241     _drivers[index]->close();
2242   }
2243   else
2244     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
2245                                      << "The index given is invalid, index must be between  0 and |"
2246                                      << _drivers.size()
2247                                      )
2248                           );
2249   END_OF(LOC);
2250 }
2251
2252 /*!
2253   Write FIELD in the file specified in the driver given by its index. Use this
2254   method for ASCII drivers (e.g. VTK_DRIVER)
2255 */
2256 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::writeAppend(int index/*=0*/, const string & driverName /*= ""*/)
2257 {
2258   const char * LOC = "FIELD<T,INTERLACING_TAG>::write(int index=0, const string & driverName = \"\") : ";
2259   BEGIN_OF(LOC);
2260
2261   if( _drivers[index] ) {
2262     _drivers[index]->openAppend();
2263     if (driverName != "") _drivers[index]->setFieldName(driverName);
2264     _drivers[index]->writeAppend();
2265     _drivers[index]->close();
2266   }
2267   else
2268     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
2269                                      << "The index given is invalid, index must be between  0 and |"
2270                                      << _drivers.size()
2271                                      )
2272                           );
2273   END_OF(LOC);
2274 }
2275
2276 /*!
2277   \internal
2278   Write FIELD with the driver which is equal to the given driver.
2279
2280   Use by MED object.
2281 */
2282 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::write(const GENDRIVER & genDriver)
2283 {
2284   const char * LOC = " FIELD<T, INTERLACING_TAG>::write(const GENDRIVER &) : ";
2285   BEGIN_OF(LOC);
2286
2287   for (unsigned int index=0; index < _drivers.size(); index++ )
2288     if ( *_drivers[index] == genDriver ) {
2289       _drivers[index]->open();
2290       _drivers[index]->write();
2291       _drivers[index]->close();
2292     }
2293
2294   END_OF(LOC);
2295
2296 }
2297
2298 /*!
2299   \internal
2300   Write FIELD with the driver which is equal to the given driver.
2301
2302   Use by MED object. Use this method for ASCII drivers (e.g. VTK_DRIVER).
2303 */
2304 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::writeAppend(const GENDRIVER & genDriver)
2305 {
2306   const char * LOC = " FIELD<T, INTERLACING_TAG>::write(const GENDRIVER &) : ";
2307   BEGIN_OF(LOC);
2308
2309   for (unsigned int index=0; index < _drivers.size(); index++ )
2310     if ( *_drivers[index] == genDriver ) {
2311       _drivers[index]->openAppend();
2312       _drivers[index]->writeAppend();
2313       _drivers[index]->close();
2314     }
2315
2316   END_OF(LOC);
2317
2318 }
2319
2320 /*!
2321   \internal
2322   Read FIELD with the driver which is equal to the given driver.
2323
2324   Use by MED object.
2325 */
2326 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::read(const GENDRIVER & genDriver)
2327 {
2328   const char * LOC = " FIELD<T, INTERLACING_TAG>::read(const GENDRIVER &) : ";
2329   BEGIN_OF(LOC);
2330
2331   for (unsigned int index=0; index < _drivers.size(); index++ )
2332     if ( *_drivers[index] == genDriver ) {
2333       _drivers[index]->open();
2334       _drivers[index]->read();
2335       _drivers[index]->close();
2336     }
2337
2338   END_OF(LOC);
2339
2340 }
2341
2342 /*!
2343   Fills in already allocated retValues array the values related to eltIdInSup.
2344   If the element does not exist in this->_support false is returned, true otherwise.
2345  */
2346 template <class T, class INTERLACING_TAG>
2347 bool FIELD<T, INTERLACING_TAG>::getValueOnElement(int eltIdInSup,T* retValues)
2348   const throw (MEDEXCEPTION)
2349 {
2350
2351   if(eltIdInSup<1)
2352     return false;
2353   if(_support->isOnAllElements())
2354     {
2355       int nbOfEltsThis=_support->getMesh()->getNumberOfElements(_support->getEntity(),MED_EN::MED_ALL_ELEMENTS);
2356       if(eltIdInSup>nbOfEltsThis)
2357         return false;
2358       const T* valsThis=getValue();
2359       for(int j=0;j<_numberOfComponents;j++)
2360         retValues[j]=valsThis[(eltIdInSup-1)*_numberOfComponents+j];
2361       return true;
2362     }
2363   else
2364     {
2365       int nbOfEltsThis=_support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
2366       const int *eltsThis=_support->getNumber(MED_EN::MED_ALL_ELEMENTS);
2367       int iThis;
2368       bool found=false;
2369       for(iThis=0;iThis<nbOfEltsThis && !found;)
2370         if(eltsThis[iThis]==eltIdInSup)
2371           found=true;
2372         else
2373           iThis++;
2374       if(!found)
2375         return false;
2376       const T* valsThis=getValue();
2377       for(int j=0;j<_numberOfComponents;j++)
2378         retValues[j]=valsThis[iThis*_numberOfComponents+j];
2379       return true;
2380     }
2381 }
2382
2383 /*!
2384   \if developper
2385   Destroy the MEDARRAY<T> in FIELD and put the new one without copy.
2386   \endif
2387 */
2388 template <class T, class INTERLACING_TAG>
2389 inline void FIELD<T, INTERLACING_TAG>::setArray(MEDMEM_Array_ * Value)
2390   throw (MEDEXCEPTION)
2391 {
2392   if (NULL != _value) delete _value ;
2393   _value=Value ;
2394 }
2395
2396 /*!
2397   \if developper
2398   Return a reference to  the MEDARRAY<T, INTERLACING_TAG> in FIELD.
2399   \endif
2400 */
2401 template <class T, class INTERLACING_TAG>
2402 inline MEDMEM_Array_ * FIELD<T, INTERLACING_TAG>::getArray() const throw (MEDEXCEPTION)
2403 {
2404   const char * LOC = "MEDMEM_Array_ * FIELD<T, INTERLACING_TAG>::getArray() : ";
2405   BEGIN_OF(LOC);
2406   END_OF(LOC);
2407   return _value ;
2408 }
2409 template <class T,class INTERLACING_TAG>  inline
2410 typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,Gauss>::Array *
2411 FIELD<T, INTERLACING_TAG>::getArrayGauss() const throw (MEDEXCEPTION)
2412 {
2413   const char * LOC = "FIELD<T, INTERLACING_TAG>::getArrayGauss() : ";
2414   BEGIN_OF(LOC);
2415
2416   if ( getGaussPresence() )
2417     return dynamic_cast<ArrayGauss *> (_value);
2418   else
2419     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<
2420                                  "The field has no Gauss Point"));
2421
2422   END_OF(LOC);
2423
2424 }
2425
2426 template <class T,class INTERLACING_TAG>  inline
2427 typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,NoGauss>::Array *
2428 FIELD<T, INTERLACING_TAG>::getArrayNoGauss() const throw (MEDEXCEPTION)
2429 {
2430   const char * LOC = "FIELD<T, INTERLACING_TAG>::getArrayNoGauss() : ";
2431   BEGIN_OF(LOC);
2432
2433   if ( ! getGaussPresence() )
2434     return dynamic_cast < ArrayNoGauss * > (_value);
2435   else
2436     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<
2437                                  "The field has Gauss Point"));
2438
2439   END_OF(LOC);
2440 }
2441
2442
2443 template <class T,class INTERLACING_TAG> inline bool
2444 FIELD<T, INTERLACING_TAG>::getGaussPresence() const throw (MEDEXCEPTION)
2445 {
2446   const char * LOC = "FIELD<T, INTERLACING_TAG>::getGaussPresence() const :";
2447   //BEGIN_OF(LOC);
2448
2449   if (_value != NULL)
2450     return _value->getGaussPresence();
2451   else
2452     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't call getGaussPresence on a null _value"));
2453
2454   //END_OF(LOC);
2455 }
2456
2457 /*!
2458   Return the actual length of the reference to values array returned by getValue.
2459   Take care of number of components and number of Gauss points by geometric type
2460 */
2461 template <class T, class INTERLACING_TAG>
2462 inline int FIELD<T, INTERLACING_TAG>::getValueLength() const
2463   throw (MEDEXCEPTION)
2464 {
2465   if ( getGaussPresence() )
2466     return dynamic_cast<ArrayGauss *>(_value)->getArraySize() ;
2467   else
2468     return dynamic_cast<ArrayNoGauss *>(_value)->getArraySize() ;
2469 }
2470
2471 /*!
2472   Return a reference to values array to read them.
2473 */
2474 template <class T, class INTERLACIN_TAG>
2475 inline const T* FIELD<T, INTERLACIN_TAG>::getValue() const throw (MEDEXCEPTION)
2476 {
2477   const char * LOC ="FIELD<T, INTERLACING_TAG>::getValue() : ";
2478   BEGIN_OF(LOC);
2479   if ( getGaussPresence() )
2480     return dynamic_cast<ArrayGauss *>(_value)->getPtr() ;
2481   else
2482     return dynamic_cast<ArrayNoGauss *>(_value)->getPtr() ;
2483 }
2484 /*!
2485   Return a reference to i^{th} row
2486   of FIELD values array.
2487   If a faster accessor is intended you may use getArray() once,
2488   then MEDMEM_Array accessors.
2489   Be careful if field support is not on all elements getRow
2490   use support->getValIndFromGlobalNumber(i).
2491 */
2492 template <class T,class INTERLACING_TAG> inline
2493 const T*
2494 FIELD<T,INTERLACING_TAG>::getRow(int i) const throw (MEDEXCEPTION)
2495 {
2496   const char * LOC = "FIELD<T,INTERLACING_TAG>::getRow(int i) : ";
2497   //BEGIN_OF(LOC);
2498
2499   int valIndex=-1;
2500   if (_support)
2501     valIndex = _support->getValIndFromGlobalNumber(i);
2502   else
2503     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
2504
2505   //cout << endl << "getRow Valindex : " << valIndex << endl;
2506   if ( getGaussPresence() )
2507     return static_cast<ArrayGauss *>(_value)->getRow(valIndex) ;
2508   else
2509     return static_cast<ArrayNoGauss *>(_value)->getRow(valIndex) ;
2510   //END_OF(LOC);
2511 }
2512
2513 /*!
2514   Return a reference to j^{th} column
2515   of FIELD values array.
2516 */
2517 template <class T,class INTERLACING_TAG> inline const T*
2518 FIELD<T,INTERLACING_TAG>::getColumn(int j) const throw (MEDEXCEPTION)
2519 {
2520   const char * LOC ="FIELD<T,INTERLACING_TAG>::getColumn(int j) : ";
2521   //BEGIN_OF(LOC);
2522   if ( getGaussPresence() )
2523     return static_cast<ArrayGauss *>(_value)->getColumn(j) ;
2524   else
2525     return static_cast<ArrayNoGauss *>(_value)->getColumn(j) ;
2526 }
2527
2528 /*!
2529   Return the value of i^{th} element and j^{th} component.
2530 */
2531 template <class T,class INTERLACING_TAG> inline T FIELD<T,INTERLACING_TAG>::getValueIJ(int i,int j) const throw (MEDEXCEPTION)
2532 {
2533   const char * LOC = "getValueIJ(..)";
2534   //BEGIN_OF(LOC);
2535   int valIndex=-1;
2536   if (_support)
2537     valIndex = _support->getValIndFromGlobalNumber(i);
2538   else
2539     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
2540
2541   if ( getGaussPresence() )
2542     return static_cast<ArrayGauss *>(_value)->getIJ(valIndex,j) ;
2543   else
2544     return static_cast<ArrayNoGauss *>(_value)->getIJ(valIndex,j) ;
2545 }
2546
2547 /*!
2548   Return the j^{th} component of k^{th} gauss points of i^{th} value.
2549 */
2550 template <class T,class INTERLACING_TAG> inline T FIELD<T,INTERLACING_TAG>::getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION)
2551 {
2552   const char * LOC = "getValueIJK(..)";
2553   //BEGIN_OF(LOC);
2554   int valIndex=-1;
2555   if (_support)
2556     valIndex = _support->getValIndFromGlobalNumber(i);
2557   else
2558     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
2559
2560   if ( getGaussPresence() )
2561     return static_cast<ArrayGauss *>(_value)->getIJK(valIndex,j,k) ;
2562   else
2563     return static_cast<ArrayNoGauss *>(_value)->getIJK(valIndex,j,k) ;
2564 }
2565
2566
2567 template <class T,class INTERLACING_TAG> const int FIELD<T,INTERLACING_TAG>::getNumberOfGeometricTypes() const throw (MEDEXCEPTION)
2568 {
2569   const char * LOC = "getNumberOfGeometricTypes(..)";
2570   BEGIN_OF(LOC);
2571   if (_support)
2572     return _support->getNumberOfTypes();
2573   else
2574     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
2575   END_OF(LOC);
2576 };
2577
2578
2579 template <class T,class INTERLACING_TAG> const GAUSS_LOCALIZATION<INTERLACING_TAG> &
2580 FIELD<T,INTERLACING_TAG>::getGaussLocalization(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION)
2581 {
2582   const char * LOC ="getGaussLocalization(MED_EN::medGeometryElement geomElement) : ";
2583   const GAUSS_LOCALIZATION_ * locPtr=0;
2584
2585   locMap::const_iterator it;
2586   if ( ( it = _gaussModel.find(geomElement)) != _gaussModel.end() ) {
2587         locPtr = (*it).second;
2588         return  *static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> *>(locPtr);
2589   }
2590   else
2591     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't find any GaussLocalization on this geometric type" ));
2592
2593 };
2594
2595 /*!
2596   Returns number of Gauss points for this medGeometryElement.
2597
2598   Note :
2599   if there is no GAUSS_LOCALIZATION having this medGeometryElement but
2600   the medGeometryElement exist in the SUPPORT, getNumberOfGaussPoints
2601   return 1
2602 */
2603 template <class T,class INTERLACING_TAG> const int FIELD<T,INTERLACING_TAG>::getNumberOfGaussPoints(MED_EN::medGeometryElement geomElement) const
2604   throw (MEDEXCEPTION)
2605 {
2606   const char * LOC ="getNumberOfGaussPoints(MED_EN::medGeometryElement geomElement) : ";
2607   const GAUSS_LOCALIZATION_ * locPtr=0;
2608
2609   locMap::const_iterator it;
2610   if ( ( it = _gaussModel.find(geomElement)) != _gaussModel.end() ) {
2611         locPtr = (*it).second;
2612         return  static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> *>(locPtr)->getNbGauss();
2613   }
2614   else
2615     if (_support)
2616       try {
2617         if ( _support->getNumberOfElements(geomElement) ) return 1;
2618       } catch ( MEDEXCEPTION & ex) {
2619         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "GeometricType not found !" )) ;
2620       }
2621     else
2622       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
2623
2624   throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Should never execute this!" ));
2625
2626 }
2627
2628 /*!
2629   Returns number of Gauss points for each geometric type.
2630
2631   Note :
2632   if there is no gauss points whatever the geometric type is
2633   it returns an exception. (renvoyer un tableau de 1 ?)
2634 */
2635 template <class T,class INTERLACING_TAG> const int * FIELD<T,INTERLACING_TAG>::getNumberOfGaussPoints() const
2636   throw (MEDEXCEPTION)
2637 {
2638   const char * LOC ="const int * getNumberOfGaussPoints(MED_EN::medGeometryElement geomElement) : ";
2639
2640   if (_value)
2641     if ( getGaussPresence() ) {
2642       return dynamic_cast<ArrayGauss *>(_value)->getNbGaussGeo()+1;
2643     } else
2644       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"value hasn't Gauss points " ));
2645
2646     else
2647       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Value not defined" ));
2648 }
2649
2650 /*!
2651   Returns number of Gauss points for element n°i.
2652   The i index is a global index (take care of previous element
2653   on different geometric type).
2654 */
2655 template <class T,class INTERLACING_TAG> const int FIELD<T,INTERLACING_TAG>::getNbGaussI(int i) const throw (MEDEXCEPTION)
2656 {
2657   const char * LOC = "getNbGaussI(..)";
2658 //   BEGIN_OF(LOC);
2659
2660   int valIndex=-1;
2661   if (_support)
2662     valIndex = _support->getValIndFromGlobalNumber(i);
2663   else
2664     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
2665
2666   if (_value)
2667    if ( getGaussPresence() )
2668      return static_cast<ArrayGauss *>(_value)->getNbGauss(valIndex) ;
2669    else
2670      return static_cast<ArrayNoGauss *>(_value)->getNbGauss(valIndex) ;
2671  else
2672    throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"_value not defined" ));
2673 //   END_OF(LOC);
2674 };
2675
2676 template <class T,class INTERLACING_TAG> const int * FIELD<T,INTERLACING_TAG>::getNumberOfElements() const throw (MEDEXCEPTION)
2677 {
2678   const char * LOC = "getNumberOfElements(..)";
2679   BEGIN_OF(LOC);
2680   if (_support)
2681     return _support->getNumberOfElements();
2682   else
2683     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
2684    END_OF(LOC);
2685 };
2686
2687 template <class T,class INTERLACING_TAG> const MED_EN::medGeometryElement  * FIELD<T,INTERLACING_TAG>::getGeometricTypes()  const throw (MEDEXCEPTION)
2688 {
2689   const char * LOC = "getGeometricTypes(..)";
2690   BEGIN_OF(LOC);
2691   if (_support)
2692     return _support->getTypes();
2693   else
2694     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
2695    END_OF(LOC);
2696 };
2697 template <class T,class INTERLACING_TAG> bool  FIELD<T,INTERLACING_TAG>::isOnAllElements() const throw (MEDEXCEPTION)
2698 {
2699   const char * LOC = "isOnAllElements(..)";
2700   BEGIN_OF(LOC);
2701   if (_support)
2702     return _support->isOnAllElements();
2703   else
2704     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
2705   END_OF(LOC);
2706 };
2707
2708
2709 /*!
2710   Copy new values array in FIELD according to the given mode.
2711
2712   Array must have right size. If not results are unpredicable.
2713 */
2714 template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValue( T* value) throw (MEDEXCEPTION) 
2715 {
2716   if ( getGaussPresence() )
2717     return dynamic_cast<ArrayGauss *>(_value)->setPtr(value) ;
2718   else
2719     return dynamic_cast<ArrayNoGauss *>(_value)->setPtr(value) ;
2720 }
2721
2722 /*!
2723   Update values array in the j^{th} row of FIELD values array with the given ones and
2724   according to specified mode.
2725 */
2726 template <class T,class INTERLACING_TAG>
2727 inline void FIELD<T,INTERLACING_TAG>::setRow( int i, T* value) throw (MEDEXCEPTION)
2728 {
2729   const char * LOC = "FIELD<T,INTERLACING_TAG>::setRow(int i, T* value) : ";
2730   int valIndex=i;
2731   if (_support)
2732     valIndex = _support->getValIndFromGlobalNumber(i);
2733   else
2734     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
2735
2736   if ( getGaussPresence() )
2737     return static_cast<ArrayGauss *>(_value)->setRow(valIndex, value) ;
2738   else
2739     return static_cast<ArrayNoGauss *>(_value)->setRow(valIndex, value) ;
2740 }
2741
2742 /*!
2743   Update values array in the j^{th} column of FIELD values array with the given ones and
2744   according to specified mode.
2745 */
2746 template <class T,class INTERLACING_TAG>
2747 inline void FIELD<T,INTERLACING_TAG>::setColumn( int j, T* value) throw (MEDEXCEPTION)
2748 {
2749   if ( getGaussPresence() )
2750     return static_cast<ArrayGauss *>(_value)->setColumn(j, value) ;
2751   else
2752     return static_cast<ArrayNoGauss *>(_value)->setColumn(j, value) ;
2753 }
2754
2755 /*!
2756   Set the value of i^{th} element and j^{th} component with the given one.
2757 */
2758 template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValueIJ(int i, int j, T value) throw (MEDEXCEPTION) 
2759 {
2760   const char * LOC = "FIELD<T,INTERLACING_TAG>::setValueIJ(int i, int j, T value) : ";
2761   int valIndex=-1;
2762   if (_support)
2763     valIndex = _support->getValIndFromGlobalNumber(i);
2764   else
2765     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
2766
2767   if ( getGaussPresence() )
2768     return static_cast<ArrayGauss *>(_value)->setIJ(valIndex,j,value) ;
2769   else
2770     return static_cast<ArrayNoGauss *>(_value)->setIJ(valIndex,j,value) ;
2771 }
2772
2773 /*
2774   METHODS
2775 */
2776
2777 /*!
2778   Fill values array with volume values.
2779 */
2780 template <class T, class INTERLACING_TAG>
2781 void FIELD<T, INTERLACING_TAG>::getVolume() const throw (MEDEXCEPTION)
2782 {
2783   const char * LOC = "FIELD<double>::getVolume() const : ";
2784   BEGIN_OF(LOC);
2785
2786   // The field has to be initilised by a non empty support and a
2787   // number of components = 1 and its value type has to be set to MED_REEL64
2788   // (ie a FIELD<double>)
2789
2790   if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64))
2791       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"));
2792
2793   END_OF(LOC);
2794 }
2795
2796 /*!
2797   Fill values array with area values.
2798 */
2799 template <class T, class INTERLACING_TAG>
2800 void FIELD<T, INTERLACING_TAG>::getArea() const throw (MEDEXCEPTION)
2801 {
2802   const char * LOC = "FIELD<double>::getArea() const : ";
2803   BEGIN_OF(LOC);
2804
2805   // The field has to be initilised by a non empty support and a
2806   // number of components = 1 and its value type has to be set to MED_REEL64
2807   // (ie a FIELD<double>)
2808
2809   if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64))
2810       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"));
2811
2812   END_OF(LOC);
2813 }
2814
2815 /*!
2816   Fill values array with length values.
2817 */
2818 template <class T, class INTERLACING_TAG>
2819 void FIELD<T, INTERLACING_TAG>::getLength() const throw (MEDEXCEPTION)
2820 {
2821   const char * LOC = "FIELD<double>::getLength() const : ";
2822   BEGIN_OF(LOC);
2823
2824   // The field has to be initilised by a non empty support and a
2825   // number of components = 1 and its value type has to be set to MED_REEL64
2826   // (ie a FIELD<double>)
2827
2828   if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64))
2829       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"));
2830
2831   END_OF(LOC);
2832 }
2833
2834 /*!
2835   Fill values array with normal values.
2836 */
2837 template <class T, class INTERLACING_TAG>
2838 void FIELD<T, INTERLACING_TAG>::getNormal() const throw (MEDEXCEPTION)
2839 {
2840   const char * LOC = "FIELD<double>::getNormal() const : ";
2841   BEGIN_OF(LOC);
2842
2843   // The field has to be initilised by a non empty support and a
2844   // number of components = 1 and its value type has to be set to MED_REEL64
2845   // (ie a FIELD<double>)
2846
2847   if (_support == (SUPPORT *) NULL)
2848       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"));
2849
2850   int dim_space = _support->getMesh()->getSpaceDimension();
2851
2852   if ((_numberOfComponents != dim_space) || (_valueType != MED_EN::MED_REEL64))
2853       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"));
2854
2855   END_OF(LOC);
2856 }
2857
2858 /*!
2859   Fill values array with barycenter values.
2860 */
2861 template <class T, class INTERLACING_TAG>
2862 void FIELD<T, INTERLACING_TAG>::getBarycenter() const throw (MEDEXCEPTION)
2863 {
2864   const char * LOC = "FIELD<double>::getBarycenter() const : ";
2865   BEGIN_OF(LOC);
2866
2867   // The field has to be initilised by a non empty support and a number of
2868   //components = space dimension and its value type has to be set to MED_REEL64
2869   // (ie a FIELD<double>)
2870
2871   if (_support == (SUPPORT *) NULL)
2872       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"));
2873
2874   int dim_space = _support->getMesh()->getSpaceDimension();
2875
2876   if ((_numberOfComponents != dim_space) || (_valueType != MED_EN::MED_REEL64))
2877       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"));
2878
2879   END_OF(LOC);
2880 }
2881
2882 /*!
2883   Fill array by using T_Analytic.
2884   WARNING : "this" must have allocated its array by setting this->_support and this->_numberOfComponents properly.
2885   Typically you should use it on a field built with constructor FIELD<T>::FIELD<T>(SUPPORT *,int nbOfComponents)
2886  */
2887 template <class T, class INTERLACING_TAG>
2888 void FIELD<T, INTERLACING_TAG>::fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION)
2889 {
2890   const char * LOC = "void FIELD<T, INTERLACING_TAG>::fillFromAnalytic(myFuncType f) : ";
2891   int i,j;
2892   if (_support == (SUPPORT *) NULL)
2893       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No Support defined."));
2894
2895   MESH * mesh = _support->getMesh();
2896   int spaceDim = mesh->getSpaceDimension();
2897   const double * coord;
2898
2899   const double * bary;
2900   FIELD<double,FullInterlace> * barycenterField=0;
2901
2902   double ** xyz=new double* [spaceDim];
2903   bool deallocateXyz=false;
2904   if(_support->getEntity()==MED_EN::MED_NODE)
2905     {
2906       if (_support->isOnAllElements())
2907         {
2908           coord=mesh->getCoordinates(MED_EN::MED_NO_INTERLACE);
2909           for(i=0; i<spaceDim; i++)
2910             xyz[i]=(double *)coord+i*_numberOfValues;
2911         }
2912       else
2913         {
2914           coord = mesh->getCoordinates(MED_EN::MED_FULL_INTERLACE);
2915           const int * nodesNumber=_support->getNumber(MED_EN::MED_ALL_ELEMENTS);
2916           for(i=0; i<spaceDim; i++)
2917             xyz[i]=new double[_numberOfValues];
2918           deallocateXyz=true;
2919           for(i=0;i<_numberOfValues;i++)
2920             {
2921               for(j=0;j<spaceDim;j++)
2922                 xyz[j][i]=coord[(nodesNumber[i]-1)*spaceDim+j];
2923             }
2924         }
2925     }
2926   else
2927     {
2928       barycenterField = mesh->getBarycenter(_support);
2929       bary=barycenterField->getValue();
2930       for(i=0; i<spaceDim; i++)
2931         xyz[i]=(double *)(bary+i*_numberOfValues);
2932     }
2933   T* valsToSet=(T*)getValue();
2934   double *temp=new double[spaceDim];
2935   for(i=0;i<_numberOfValues;i++)
2936   {
2937     for(j=0;j<spaceDim;j++)
2938       temp[j]=xyz[j][i];
2939     f(temp,valsToSet+i*_numberOfComponents);
2940   }
2941   delete [] temp;
2942   if(barycenterField)
2943     delete barycenterField;
2944   if(deallocateXyz)
2945     for(j=0;j<spaceDim;j++)
2946       delete [] xyz[j];
2947   delete [] xyz;
2948 }
2949
2950 }//End namespace MEDMEM
2951
2952 #endif /* FIELD_HXX */