1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
32 #include "MEDMEM_Utilities.hxx"
33 #include "MEDMEM_MedVersion.hxx"
34 #include "MEDMEM_Exception.hxx"
35 #include "MEDMEM_define.hxx"
36 #include "MEDMEM_Support.hxx"
37 #include "MEDMEM_Unit.hxx"
38 #include "MEDMEM_nArray.hxx"
39 #include "MEDMEM_GenDriver.hxx"
40 #include "MEDMEM_RCBase.hxx"
41 #include "MEDMEM_ArrayInterface.hxx"
42 #include "MEDMEM_SetInterlacingType.hxx"
43 #include "MEDMEM_FieldForward.hxx"
44 #include "MEDMEM_GaussLocalization.hxx"
45 #include "InterpKernelGaussCoords.hxx"
46 #include "PointLocator.hxx"
63 struct MinMax<double> {
64 static double getMin() { return DBL_MIN; }
65 static double getMax() { return DBL_MAX; }
70 static int getMin() { return INT_MIN; }
71 static int getMax() { return INT_MAX; }
74 template < typename T > struct SET_VALUE_TYPE {
75 static const MED_EN::med_type_champ _valueType = MED_EN::MED_UNDEFINED_TYPE;};
76 template < > struct SET_VALUE_TYPE<double> {
77 static const MED_EN::med_type_champ _valueType = MED_EN::MED_REEL64; };
78 template < > struct SET_VALUE_TYPE<int> {
79 static const MED_EN::med_type_champ _valueType = MED_EN::MED_INT32; };
81 /*!\defgroup FIELD_io Reading and writing files
83 Fields can be read or written to/from MED files.
87 For reading a field a typical use consists in :
88 - reading the mesh associated on which the field lies
89 - read the field, specifying its time step and order number
93 //reading mesh from file
94 MESH mesh(MED_DRIVER, "file.med", "my_Mesh");
95 //reading the field from the file
96 FIELD<double> field(group,MED_DRIVER,"file.med","my_Field",1,1,&mesh);
99 It is also possible to read a field without specifying its support. In this case, the field constructor
100 creates a support with no link to the initial mesh:
102 FIELD<double> field(MED_DRIVER, "file.med", "myField",1,1);
103 SUPPORT* support= field->getSupport();
106 See also \ref FIELD_constructors
110 When it comes to write fields, it is enough to call write() method.
111 A typical use will be :
114 mesh.write(MED_DRIVER, "myResultFile.med");
115 field.write(MED_DRIVER, "myResultFile.med");
118 \defgroup FIELD_constructors
120 The different field constructors correspond to the two main
121 ways a field is used :
122 - either it is read from a file to be consulted,
123 - or it can be created from scratch with a link to a support on which the values will be built.
125 \defgroup FIELD_algo Numerical operations on fields
126 This section groups together the different operators that enable the user to
127 treat the FIELD objects as high-level numerical arrays, giving operators for
128 numerical treatment (overloading of basic operators, algorithms, etc...)
130 \defgroup FIELD_getset Basic Get/Set operations
132 This sections groups together the basic operations
133 that describe access to all the elements constitutive of the description of the field :
135 - time iteration number(compulsory),
136 - inner loop iteration number(compulsory),
138 - description(optional),
139 - number of components(compulsory),
140 - components names(optional),
141 - components description(optional).
143 Some of these items are compulsory because they are essential to the field in order to define
144 its structure or to be identified inside a MED file during the write process. The other ones
145 are there for additional information and can be overlooked if not necessary.
147 When creating a field by reading a file, all the parameters are set according to the file
148 data and can be consulted via the get methods. When creating a file from scratch, the
149 name and number of components are set by the constructor, but the other items have to be
150 set via the setXXX methods.
152 \defgroup FIELD_gauss Gauss points
154 In MED, it is possible to declare a Gauss model that
155 describes the location of Gauss points in a reference cell.
156 This Gauss model definition is contained in the
157 \a GAUSS_LOCALIZATION class. A \a GAUSS_LOCALIZATION object
158 is associated to a field and to a type.
160 It is not permitted to define a Gauss model in a polygonal
161 or polyhedric element.
163 The Gauss model can be :
164 - loaded from a MED file,
165 - written to a MED file,
166 - used to define a FIELD with multiple localizations per element.
168 \section gauss_constructors Constructing a Gauss Model
170 A Gauss model can be constructed with the following constructor :
171 \param locName defines a name associated with the gauss model
172 \param typeGeo names the type to which the Gauss model is assocaited
173 \param nGauss defines the number of Gauss points
174 \param cooRef defines an array giving the coordinates of the nodes of the reference element (dimension : spaceDimension * number of nodes for type \a typeGeo)
175 \param cooGauss defines an array giving the coordinates of the nodes of the Gauss points (dimension : spaceDimension * \a nGauss
177 \param wg weights associated with each Gauss point (dimension : \a nGauss)
179 Example : in 2D, a Gauss model definition for a triangle
180 would be written as :
183 string locname("gauss model");
184 double cooRef[6] ={0.0, 0.0, 1.0, 0.0, 0.0, 1.0};
185 double cooGauss[6]={0.2, 0.2, 0.8, 0.1, 0.1, 0.8};
186 double wg[3]={0.3334, 0.3334, 0.3334};
187 GAUSS_LOCALIZATION model(locname,
200 This class contains all the informations related with a template class FIELD :
201 - Components descriptions
202 - Time step description
203 - Location of the values (a SUPPORT class)
206 class MEDMEM_EXPORT FIELD_ : public RCBASE // GENERIC POINTER TO a template <class T, class INTERLACING_TAG> class FIELD
224 string _description ;
227 Pointer to the support the field deals with.
230 const SUPPORT * _support ;
234 Number of field's components.
237 int _numberOfComponents ;
240 Number of field's values.
241 doesn't take care of _numberOfComponents
242 and number of Gauss points.
245 int _numberOfValues ;
249 Array of size _numberOfComponents. \n
250 (constant, scalar, vector, tensor)\n
251 We could use an array of integer to store
252 numbers of values: \n
254 - space dimension for vector,\n
255 - space dimension square for tensor.\n
256 So numbers of values per entities would be
257 sum of _componentsTypes array.
259 Not implemented yet! All type are scalar !
262 vector<int> _componentsTypes ;
265 Array of size _numberOfComponents
266 storing components names if any.
269 vector<string> _componentsNames;
272 Array of size _numberOfComponents
273 storing components descriptions if any.
276 vector<string> _componentsDescriptions;
279 Array of size _numberOfComponents
280 storing components units if any.
283 vector<UNIT> _componentsUnits;
286 Array of size _numberOfComponents
287 storing components units if any.
290 vector<string> _MEDComponentsUnits;
293 Iteration number of the field.
296 int _iterationNumber ;
305 Order number of the field.
311 At the initialization step of the field using the constructors; this attribute,
312 the value type (integer or real) , is set automatically. There is a get method
313 but not a set method for this attribute.
316 MED_EN::med_type_champ _valueType ;
319 At the initialization step of the field using the constructors; this attribute,
320 the interlacing type (full interlace or no interlace field value storage), is set
321 automatically. There is a get method but not a set method for this attribute.
324 MED_EN::medModeSwitch _interlacingType;
326 vector<GENDRIVER *> _drivers; // Storage of the drivers currently in use
327 static void _checkFieldCompatibility(const FIELD_& m, const FIELD_& n, bool checkUnit=true) throw (MEDEXCEPTION);
328 static void _deepCheckFieldCompatibility(const FIELD_& m, const FIELD_& n, bool checkUnit=true) throw (MEDEXCEPTION);
329 void _checkNormCompatibility(const FIELD<double>* p_field_volume=NULL,
330 const bool nodalAllowed = false) const throw (MEDEXCEPTION);
331 FIELD<double>* _getFieldSize(const SUPPORT *subSupport=NULL) const;
341 FIELD_(const SUPPORT * Support, const int NumberOfComponents);
346 FIELD_(const FIELD_ &m);
355 friend class MED_MED_RDONLY_DRIVER21;
356 friend class MED_MED_WRONLY_DRIVER21;
357 friend class MED_MED_RDWR_DRIVER21;
358 friend class MED_MED_RDONLY_DRIVER22;
359 friend class MED_MED_WRONLY_DRIVER22;
360 friend class MED_MED_RDWR_DRIVER22;
361 friend class VTK_MED_DRIVER;
363 FIELD_& operator=(const FIELD_ &m);
365 virtual void rmDriver(int index=0);
373 /*! Creates a driver for reading/writing fields in a file.
374 \param driverType specifies the file type (MED_DRIVER, VTK_DRIVER)
375 \param fileName name of the output file
376 \param driverFieldName name of the field
377 \param access specifies whether the file is opened for read, write or both.
380 virtual int addDriver(driverTypes driverType,
381 const string & fileName="Default File Name.med",
382 const string & driverFieldName="Default Field Nam",
383 MED_EN::med_mode_acces access=MED_EN::RDWR) ;
385 virtual int addDriver( GENDRIVER & driver);
386 virtual void read (driverTypes driverType, const std::string & fileName);
387 virtual void read (const GENDRIVER &);
388 virtual void read(int index=0);
389 virtual void openAppend( void );
390 virtual void write(const GENDRIVER &, MED_EN::med_mode_acces medMode=MED_EN::RDWR);
391 virtual void write(driverTypes driverType,
392 const std::string & fileName,
393 MED_EN::med_mode_acces medMode=MED_EN::RDWR);
395 /*! Triggers the writing of the field with respect to the driver handle
396 \a index given by \a addDriver(...) method. */
397 virtual void write(int index=0);
398 /*!\if MEDMEM_ug @} \endif */
400 virtual void writeAppend(const GENDRIVER &);
401 virtual void writeAppend(int index=0, const string & driverName="");
403 inline void setName(const string Name);
404 inline string getName() const;
405 inline void setDescription(const string Description);
406 inline string getDescription() const;
407 inline const SUPPORT * getSupport() const;
408 inline void setSupport(const SUPPORT * support);
409 inline void setNumberOfComponents(const int NumberOfComponents);
410 inline int getNumberOfComponents() const;
411 inline void setNumberOfValues(const int NumberOfValues);
412 inline int getNumberOfValues() const;
413 inline void setComponentsNames(const string * ComponentsNames);
414 inline void setComponentName(int i, const string ComponentName);
415 inline const string * getComponentsNames() const;
416 inline string getComponentName(int i) const;
417 inline void setComponentsDescriptions(const string * ComponentsDescriptions);
418 inline void setComponentDescription(int i, const string ComponentDescription);
419 inline const string * getComponentsDescriptions() const;
420 inline string getComponentDescription(int i) const;
422 // provisoire : en attendant de regler le probleme des unites !
423 inline void setComponentsUnits(const UNIT * ComponentsUnits);
424 inline const UNIT * getComponentsUnits() const;
425 inline const UNIT * getComponentUnit(int i) const;
426 inline void setMEDComponentsUnits(const string * MEDComponentsUnits);
427 inline void setMEDComponentUnit(int i, const string MEDComponentUnit);
428 inline const string * getMEDComponentsUnits() const;
429 inline string getMEDComponentUnit(int i) const;
431 inline void setIterationNumber(int IterationNumber);
432 inline int getIterationNumber() const;
433 inline void setTime(double Time);
434 inline double getTime() const;
435 inline void setOrderNumber(int OrderNumber);
436 inline int getOrderNumber() const;
438 inline MED_EN::med_type_champ getValueType () const;
439 inline MED_EN::medModeSwitch getInterlacingType() const;
440 virtual inline bool getGaussPresence() const throw (MEDEXCEPTION);
442 void copyGlobalInfo(const FIELD_& m);
449 \addtogroup FIELD_getset
454 Sets FIELD name. The length should not exceed MED_TAILLE_NOM
455 as defined in Med (i.e. 32 characters).
457 inline void FIELD_::setName(const string Name)
464 inline string FIELD_::getName() const
469 Sets FIELD description. The length should not exceed MED_TAILLE_DESC as defined in Med (i.e. 200 characters).
471 inline void FIELD_::setDescription(const string Description)
473 _description=Description;
476 Gets FIELD description.
478 inline string FIELD_::getDescription() const
483 Sets FIELD number of components.
485 inline void FIELD_::setNumberOfComponents(const int NumberOfComponents)
487 _numberOfComponents=NumberOfComponents;
488 _componentsTypes.resize(_numberOfComponents);
489 _componentsNames.resize(_numberOfComponents);
490 _componentsDescriptions.resize(_numberOfComponents);
491 _componentsUnits.resize(_numberOfComponents);
492 _MEDComponentsUnits.resize(_numberOfComponents);
495 Gets FIELD number of components.
497 inline int FIELD_::getNumberOfComponents() const
499 return _numberOfComponents ;
502 Sets FIELD number of values.
504 It must be the same than in the associated SUPPORT object.
506 inline void FIELD_::setNumberOfValues(const int NumberOfValues)
508 _numberOfValues=NumberOfValues;
511 Gets FIELD number of value.
513 inline int FIELD_::getNumberOfValues() const
515 return _numberOfValues ;
519 Sets FIELD components names.
521 Duplicates the ComponentsNames string array to put components names in
522 FIELD. ComponentsNames size must be equal to number of components.
524 inline void FIELD_::setComponentsNames(const string * ComponentsNames)
526 _componentsNames.resize(_numberOfComponents);
527 for (int i=0; i<_numberOfComponents; i++)
528 _componentsNames[i]=ComponentsNames[i] ;
531 Sets FIELD i^th component name.
533 i must be >=1 and <= number of components.
536 inline void FIELD_::setComponentName(int i, const string ComponentName)
538 const char * LOC = " FIELD_::setComponentName() : ";
540 if( i<1 || i>_numberOfComponents )
541 throw MEDEXCEPTION(STRING(LOC)<<" invalid index" );
543 _componentsNames[i-1]=ComponentName ;
546 Gets a reference to the string array which contain the components names.
548 This Array size is equal to number of components
550 inline const string * FIELD_::getComponentsNames() const
552 return &(_componentsNames[0]) ;
555 Gets the name of the i^th component.
558 inline string FIELD_::getComponentName(int i) const
560 const char * LOC = " FIELD_::getComponentName() : ";
562 if( i<1 || i>_numberOfComponents )
563 throw MEDEXCEPTION(STRING(LOC)<<" invalid index" );
565 return _componentsNames[i-1] ;
568 Sets FIELD components descriptions.
570 Duplicates the ComponentsDescriptions string array to put components
571 descriptions in FIELD.
572 ComponentsDescriptions size must be equal to number of components.
574 inline void FIELD_::setComponentsDescriptions(const string * ComponentsDescriptions)
576 _componentsDescriptions.resize(_numberOfComponents);
577 for (int i=0; i<_numberOfComponents; i++)
578 _componentsDescriptions[i]=ComponentsDescriptions[i] ;
581 Sets FIELD i^th component description.
583 i must be >=1 and <= number of components.
586 inline void FIELD_::setComponentDescription(int i,const string ComponentDescription)
588 const char * LOC = " FIELD_::setComponentDescription() : ";
590 if( i<1 || i>_numberOfComponents )
591 throw MEDEXCEPTION(STRING(LOC)<<" invalid index" );
593 _componentsDescriptions[i-1]=ComponentDescription ;
596 Gets a reference to the string array which contain the components descriptions.
598 This Array size is equal to number of components
600 inline const string * FIELD_::getComponentsDescriptions() const
602 return &(_componentsDescriptions[0]);
605 Gets the description of the i^th component.
608 inline string FIELD_::getComponentDescription(int i) const
610 const char * LOC = " FIELD_::setComponentDescription() : ";
612 if( i<1 || i>_numberOfComponents )
613 throw MEDEXCEPTION(STRING(LOC)<<" invalid index" );
615 return _componentsDescriptions[i-1];
620 Sets FIELD components UNIT.
622 Duplicates the ComponentsUnits UNIT array to put components
624 ComponentsUnits size must be equal to number of components.
627 inline void FIELD_::setComponentsUnits(const UNIT * ComponentsUnits)
629 _componentsUnits.resize(_numberOfComponents);
630 for (int i=0; i<_numberOfComponents; i++)
631 _componentsUnits[i]=ComponentsUnits[i] ;
634 Gets a reference to the UNIT array which contain the components units.
636 This array size is equal to number of components
639 inline const UNIT * FIELD_::getComponentsUnits() const
641 return &(_componentsUnits[0]);
644 Gets the UNIT of the i^th component.
647 inline const UNIT * FIELD_::getComponentUnit(int i) const
649 const char * LOC = " FIELD_::getComponentUnit() : ";
651 if( i<1 || i>_numberOfComponents )
652 throw MEDEXCEPTION(STRING(LOC)<<" invalid index" );
654 return &_componentsUnits[i-1] ;
657 Sets FIELD components unit.
659 Duplicates the MEDComponentsUnits string array to put components
661 MEDComponentsUnits size must be equal to number of components.
664 inline void FIELD_::setMEDComponentsUnits(const string * MEDComponentsUnits)
666 _MEDComponentsUnits.resize(_numberOfComponents);
667 for (int i=0; i<_numberOfComponents; i++)
668 _MEDComponentsUnits[i]=MEDComponentsUnits[i] ;
671 Sets FIELD i^th component unit.
673 i must be >=1 and <= number of components.
676 inline void FIELD_::setMEDComponentUnit(int i, const string MEDComponentUnit)
678 const char * LOC = " FIELD_::setMEDComponentUnit() : ";
680 if( i<1 || i>_numberOfComponents )
681 throw MEDEXCEPTION(STRING(LOC)<<" invalid index" );
683 _MEDComponentsUnits[i-1]=MEDComponentUnit ;
686 Gets a reference to the string array which contain the components units.
688 This array size is equal to number of components
690 inline const string * FIELD_::getMEDComponentsUnits() const
692 return &(_MEDComponentsUnits[0]);
695 Gets the string for unit of the i^th component.
698 inline string FIELD_::getMEDComponentUnit(int i) const
700 const char * LOC = " FIELD_::getMEDComponentUnit() : ";
702 if( i<1 || i>_numberOfComponents )
703 throw MEDEXCEPTION(STRING(LOC)<<" invalid index" );
705 return _MEDComponentsUnits[i-1] ;
708 Sets the iteration number where FIELD has been calculated.
710 inline void FIELD_::setIterationNumber(int IterationNumber)
712 _iterationNumber=IterationNumber;
715 Gets the iteration number where FIELD has been calculated.
717 inline int FIELD_::getIterationNumber() const
719 return _iterationNumber ;
722 Sets the time when FIELD has been calculated.
724 inline void FIELD_::setTime(double Time)
729 Gets the time when FIELD has been calculated.
731 inline double FIELD_::getTime() const
736 Sets the order number where FIELD has been calculated.
738 It corresponds to internal iteration during one time step.
740 inline void FIELD_::setOrderNumber(int OrderNumber)
742 _orderNumber=OrderNumber ;
745 Gets the order number where FIELD has been calculated.
747 inline int FIELD_::getOrderNumber() const
749 return _orderNumber ;
752 Gets a reference to the SUPPORT object associated to FIELD.
754 inline const SUPPORT * FIELD_::getSupport() const
759 Sets the reference to the SUPPORT object associated to FIELD.
761 Reference is not duplicate, so it must not be deleted.
763 inline void FIELD_::setSupport(const SUPPORT * support)
765 //A.G. Addings for RC
766 if(_support!=support)
769 _support->removeReference();
772 _support->addReference();
776 Gets the FIELD med value type (MED_INT32 or MED_REEL64).
778 inline MED_EN::med_type_champ FIELD_::getValueType () const
784 Gets the FIELD med interlacing type (MED_FULL_INTERLACE or MED_NO_INTERLACE).
786 inline MED_EN::medModeSwitch FIELD_::getInterlacingType () const
788 return _interlacingType ;
790 /*!\if MEDMEM_ug @} \endif*/
793 \addtogroup FIELD_gauss
798 Determines whether the field stores several Gauss points per element.
800 inline bool FIELD_::getGaussPresence() const throw (MEDEXCEPTION)
802 const char * LOC = "FIELD_::getGaussPresence() : ";
803 throw MEDEXCEPTION(STRING(LOC) << " This FIELD_ doesn't rely on a FIELD<T>" );
806 /*!\if MEDMEM_ug @} \endif*/
808 } //End namespace MEDMEM
810 /////////////////////////
811 // END OF CLASS FIELD_ //
812 /////////////////////////
816 This template class contains informations related with a FIELD :
817 - Values of the field, their type (real or integer), the storage mode (full interlace,
818 no interlace or no interlace by type).
825 template<class T2> class MED_FIELD_RDONLY_DRIVER;
826 template<class T2> class MED_FIELD_WRONLY_DRIVER;
827 template<class T2> class VTK_FIELD_DRIVER;
831 class INTERLACING_TAG
832 > class FIELD : public FIELD_
836 typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,NoGauss>::Array ArrayNoGauss;
837 typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,Gauss>::Array ArrayGauss;
838 typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo;
839 typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
840 typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,NoGauss>::Array ArrayNoByType;
841 typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,Gauss>::Array ArrayNoByTypeGauss;
842 typedef MEDMEM_Array_ Array;
843 typedef T ElementType;
844 typedef INTERLACING_TAG InterlacingTag;
845 typedef map<MED_EN::medGeometryElement,GAUSS_LOCALIZATION_*> locMap;
847 // array of value of type T
850 // MESH, to be used for field reading from a file (if desired to link
851 // to existing support instead of new support creation for the field)
858 map<MED_EN::medGeometryElement,GAUSS_LOCALIZATION_*> _gaussModel; //A changer quand les drivers seront template de l'entrelacement
860 static T _scalarForPow;
864 void _operation(const FIELD& m,const FIELD& n, const char* Op);
865 void _operationInitialize(const FIELD& m,const FIELD& n, const char* Op);
866 void _add_in_place(const FIELD& m,const FIELD& n);
867 void _sub_in_place(const FIELD& m,const FIELD& n);
868 void _mul_in_place(const FIELD& m,const FIELD& n);
869 void _div_in_place(const FIELD& m,const FIELD& n) throw (MEDEXCEPTION);
872 FIELD(const FIELD &m);
873 FIELD(const SUPPORT * Support, const int NumberOfComponents) throw (MEDEXCEPTION);
874 FIELD(driverTypes driverType,
875 const string & fileName, const string & fieldDriverName,
876 const int iterationNumber=-1, const int orderNumber=-1,
878 throw (MEDEXCEPTION);
879 FIELD(const SUPPORT * Support, driverTypes driverType,
880 const string & fileName="", const string & fieldName="",
881 const int iterationNumber = -1, const int orderNumber = -1)
882 throw (MEDEXCEPTION);
886 FIELD & operator=(const FIELD &m);
887 FIELD & operator=(T value);
888 FIELD *operator+(const FIELD& m) const;
889 FIELD *operator-(const FIELD& m) const;
890 FIELD *operator*(const FIELD& m) const;
891 FIELD *operator/(const FIELD& m) const;
892 FIELD *operator-() const;
893 FIELD& operator+=(const FIELD& m);
894 FIELD& operator-=(const FIELD& m);
895 FIELD& operator*=(const FIELD& m);
896 FIELD& operator/=(const FIELD& m);
898 void applyLin(T a, T b, int icomp);
899 static FIELD* add(const FIELD& m, const FIELD& n);
900 static FIELD* addDeep(const FIELD& m, const FIELD& n);
901 static FIELD* sub(const FIELD& m, const FIELD& n);
902 static FIELD* subDeep(const FIELD& m, const FIELD& n);
903 static FIELD* mul(const FIELD& m, const FIELD& n);
904 static FIELD* mulDeep(const FIELD& m, const FIELD& n);
905 static FIELD* div(const FIELD& m, const FIELD& n);
906 static FIELD* divDeep(const FIELD& m, const FIELD& n);
907 double normMax() const throw (MEDEXCEPTION);
909 //------- TDG and BS addings
911 void getMinMax(T &vmin, T &vmax) throw (MEDEXCEPTION);
912 vector<int> getHistogram(int &nbint) throw (MEDEXCEPTION);
913 FIELD<double>* buildGradient() const throw (MEDEXCEPTION);
914 FIELD<double>* buildNorm2Field() const throw (MEDEXCEPTION);
916 //-------------------
918 double norm2() const throw (MEDEXCEPTION);
919 void applyLin(T a, T b);
920 template <T T_function(T)> void applyFunc();
921 void applyPow(T scalar);
922 static FIELD* scalarProduct(const FIELD& m, const FIELD& n, bool deepCheck=false);
923 double normL2(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
924 double normL2(const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
925 double normL1(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
926 double normL1(const FIELD<double,FullInterlace> * p_field_volume=NULL) const;
927 double integral(const SUPPORT *subSupport=NULL) const throw (MEDEXCEPTION);
928 FIELD* extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION);
930 friend class MED_FIELD_RDONLY_DRIVER<T>;
931 friend class MED_FIELD_WRONLY_DRIVER<T>;
932 friend class VTK_FIELD_DRIVER<T>;
935 void rmDriver(int index=0);
936 int addDriver(driverTypes driverType,
937 const string & fileName="Default File Name.med",
938 const string & driverFieldName="Default Field Name",
939 MED_EN::med_mode_acces access=MED_EN::RDWR) ;
941 int addDriver(GENDRIVER & driver);
943 void allocValue(const int NumberOfComponents);
944 void allocValue(const int NumberOfComponents, const int LengthValue);
948 inline void read(int index=0);
949 inline void read(const GENDRIVER & genDriver);
950 inline void read(driverTypes driverType, const std::string& filename);
951 inline void write(int index=0);
952 inline void write(const GENDRIVER &, MED_EN::med_mode_acces medMode=MED_EN::RDWR);
953 inline void write(driverTypes driverType,
954 const std::string& filename,
955 MED_EN::med_mode_acces medMode=MED_EN::RDWR);
957 inline void writeAppend(int index=0, const string & driverName = "");
958 inline void writeAppend(const GENDRIVER &);
960 inline MEDMEM_Array_ * getArray() const throw (MEDEXCEPTION);
961 inline ArrayGauss * getArrayGauss() const throw (MEDEXCEPTION);
962 inline ArrayNoGauss * getArrayNoGauss() const throw (MEDEXCEPTION);
963 inline bool getGaussPresence() const throw (MEDEXCEPTION);
965 inline int getValueLength() const throw (MEDEXCEPTION);
968 \addtogroup FIELD_value
971 /*! Returns a pointer to the value array.*/
972 inline const T* getValue() const throw (MEDEXCEPTION);
973 inline const T* getRow(int i) const throw (MEDEXCEPTION);
974 inline const T* getColumn(int j) const throw (MEDEXCEPTION);
976 Returns the value of \f$ i^{th} \f$ element and \f$ j^{th}\f$ component.
977 This method only works with fields having no particular Gauss point
978 definition (i.e., fields having one value per element).
979 This method makes the retrieval of the value independent from the
980 interlacing pattern, but it is slower than the complete retrieval
981 obtained by the \b getValue() method.
984 inline T getValueIJ(int i,int j) const throw (MEDEXCEPTION);
987 Returns the \f$ j^{th}\f$ component of \f$ k^{th}\f$ Gauss points of \f$ i^{th}\f$ value.
988 This method is compatible with elements having more than one Gauss point.
989 This method makes the retrieval of the value independent from the
990 interlacing pattern, but it is slower than the complete retrieval
991 obtained by the \b getValue() method.
993 inline T getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION);
995 inline int getValueByTypeLength(int t) const throw (MEDEXCEPTION);
996 inline const T* getValueByType(int t) const throw (MEDEXCEPTION);
997 inline T getValueIJByType(int i,int j,int t) const throw (MEDEXCEPTION);
998 inline T getValueIJKByType(int i,int j,int k,int t) const throw (MEDEXCEPTION);
1001 The following example describes the creation of a FIELD.
1003 \example FIELDcreate.cxx
1005 \if MEDMEM_ug @} \endif */
1007 bool getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION);
1008 void getValueOnPoint(const double* coords, double* output) const throw (MEDEXCEPTION);
1009 void getValueOnPoints(int nb_points, const double* coords, double* output) const throw (MEDEXCEPTION);
1011 const int getNumberOfGeometricTypes() const throw (MEDEXCEPTION);
1012 const GAUSS_LOCALIZATION<INTERLACING_TAG> & getGaussLocalization(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
1013 const GAUSS_LOCALIZATION<INTERLACING_TAG> * getGaussLocalizationPtr(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
1014 const GAUSS_LOCALIZATION_* getGaussLocalizationRoot(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
1015 void setGaussLocalization(MED_EN::medGeometryElement geomElement, const GAUSS_LOCALIZATION<INTERLACING_TAG> & gaussloc);
1016 void setGaussLocalization(MED_EN::medGeometryElement geomElement, GAUSS_LOCALIZATION_* gaussloc);
1017 const int * getNumberOfGaussPoints() const throw (MEDEXCEPTION);
1018 const int getNumberOfGaussPoints( MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
1019 const int getNbGaussI(int i) const throw (MEDEXCEPTION);
1020 const int * getNumberOfElements() const throw (MEDEXCEPTION);
1021 const MED_EN::medGeometryElement * getGeometricTypes() const throw (MEDEXCEPTION);
1022 bool isOnAllElements() const throw (MEDEXCEPTION);
1024 inline void setArray(MEDMEM_Array_ *value) throw (MEDEXCEPTION);
1026 FIELD<double, FullInterlace>* getGaussPointsCoordinates() const throw (MEDEXCEPTION);
1029 \addtogroup FIELD_value
1034 This method makes it possible to have the field pointing to
1035 an existing value array. The ordering of the elements in the value array must
1036 conform to the MEDMEM ordering (I,K,J) : the outer loop is on the elements,
1037 the intermediate loop is on the Gauss points, the inner loop is on
1040 inline void setValue( T* value) throw (MEDEXCEPTION);
1041 inline void setRow( int i, T* value) throw (MEDEXCEPTION);
1042 inline void setColumn( int i, T* value) throw (MEDEXCEPTION);
1044 Sets the value of \f$ i^{th} \f$ element and \f$ j^{th}\f$ component with \a value.
1046 inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION);
1047 /*! \if MEDMEM_ug @} \endif */
1048 inline void setValueIJK(int i, int j, int k, T value) throw (MEDEXCEPTION);
1049 inline void setValueIJByType(int i, int j, int t, T value) throw (MEDEXCEPTION);
1050 inline void setValueIJKByType(int i, int j, int k, int t, T value) throw (MEDEXCEPTION);
1052 typedef void (*myFuncType)(const double *,T*);
1053 void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION);
1054 typedef void (*myFuncType2)(const T *,T*);
1055 FIELD<T,INTERLACING_TAG> *execFunc(int nbOfComponents, myFuncType2 f) throw (MEDEXCEPTION);
1059 #include "MEDMEM_DriverFactory.hxx"
1063 template <class T,class INTERLACING_TAG> T FIELD<T, INTERLACING_TAG>::_scalarForPow=1;
1065 // --------------------
1066 // Implemented Methods
1067 // --------------------
1070 Constructor with no parameter, most of the attribut members are set to NULL.
1072 template <class T, class INTERLACING_TAG>
1073 FIELD<T, INTERLACING_TAG>::FIELD():FIELD_()
1075 MESSAGE_MED("Constructeur FIELD sans parametre");
1077 //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
1078 ASSERT_MED(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE);
1079 FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
1081 //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
1082 ASSERT_MED(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE);
1083 FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
1085 _value = ( ArrayNoGauss * ) NULL;
1087 _mesh = ( MESH* ) NULL;
1091 \addtogroup FIELD_constructors FIELD<T> constructors
1096 Constructor that allocates the value array with the dimensions provided by
1097 \a NumberOfComponents and the dimension of \a Support. The value array is
1098 allocated but not initialized.
1099 This constructor does not allow the creation of fields with Gauss points.
1100 \param Support support on which the field lies
1101 \param NumberOfComponents number of components of the variable stored. For instance,
1102 it will be 3 for a (vx,vy,vz) vector.
1105 FIELD<double> field (support, 3);
1106 int nbelem = support->getNumberOfElements(MED_ALL_ELEMENTS);
1107 for (int i=1; i<=nbelem; i++)
1109 field->setValueIJ(i,j,0.0);
1112 template <class T, class INTERLACING_TAG>
1113 FIELD<T, INTERLACING_TAG>::FIELD(const SUPPORT * Support,
1114 const int NumberOfComponents) throw (MEDEXCEPTION) :
1115 FIELD_(Support, NumberOfComponents),_value(NULL)
1117 const char* LOC = "FIELD<T>::FIELD(const SUPPORT * Support, const int NumberOfComponents)";
1121 //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
1122 ASSERT_MED(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE)
1123 FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
1125 //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
1126 ASSERT_MED(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE)
1127 FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
1131 // becarefull about the numbre of gauss point
1132 _numberOfValues = Support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
1134 #if defined(_DEBUG_) || defined(_DEBUG)
1135 catch (MEDEXCEPTION &ex)
1137 catch (MEDEXCEPTION )
1140 MESSAGE_MED("No value defined ! ("<<ex.what()<<")");
1142 MESSAGE_MED("FIELD : constructeur : "<< _numberOfValues <<" et "<< NumberOfComponents);
1143 if ( _numberOfValues > 0 )
1145 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE )
1147 const int * nbelgeo = Support->getNumberOfElements();
1148 vector<int> nbelgeoc( Support->getNumberOfTypes() + 1 );
1150 for ( int t = 1; t < (int)nbelgeoc.size(); ++t )
1151 nbelgeoc[t] = nbelgeoc[t-1] + nbelgeo[t-1];
1152 _value = new ArrayNoByType (_numberOfComponents,_numberOfValues,
1153 Support->getNumberOfTypes(), &nbelgeoc[0]);
1157 _value = new ArrayNoGauss (_numberOfComponents,_numberOfValues);
1161 _mesh = ( MESH* ) NULL;
1172 template <class T, class INTERLACING_TAG> void FIELD<T, INTERLACING_TAG>::init ()
1179 template <class T, class INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::FIELD(const FIELD & m):
1182 MESSAGE_MED("Constructeur FIELD de recopie");
1184 // RECOPIE PROFONDE <> de l'operateur= Rmq from EF
1185 if (m._value != NULL)
1187 if ( m.getGaussPresence() )
1188 _value = new ArrayGauss( *(static_cast< ArrayGauss * > (m._value) ) ,false);
1190 _value = new ArrayNoGauss( *(static_cast< ArrayNoGauss * > (m._value)) ,false);
1193 _value = (ArrayNoGauss *) NULL;
1194 locMap::const_iterator it;
1195 for ( it = m._gaussModel.begin();it != m._gaussModel.end(); it++ )
1196 _gaussModel[static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ((*it).second)->getType()]=
1197 new GAUSS_LOCALIZATION<INTERLACING_TAG>(
1198 *static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ( (*it).second )
1201 _valueType = m._valueType;
1202 _interlacingType = m._interlacingType;
1203 //drivers = m._drivers;
1206 _mesh->addReference();
1214 template <class T, class INTERLACING_TAG>
1215 FIELD<T, INTERLACING_TAG> & FIELD<T, INTERLACING_TAG>::operator=(const FIELD &m)
1217 MESSAGE_MED("Appel de FIELD<T>::operator=") ;
1218 if ( this == &m) return *this;
1220 // copy values array
1221 FIELD_::operator=(m); // Driver are ignored & ?copie su pointeur de Support?
1223 _value = m._value; //PROBLEME RECOPIE DES POINTEURS PAS COHERENT AVEC LE
1224 //CONSTRUCTEUR PAR RECOPIE
1225 //CF :Commentaire dans MEDMEM_Array
1226 locMap::const_iterator it;
1227 for ( it = m._gaussModel.begin();it != m._gaussModel.end(); it++ )
1228 _gaussModel[static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ((*it).second)->getType()]=
1229 new GAUSS_LOCALIZATION<INTERLACING_TAG>(
1230 *static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ( (*it).second )
1233 _valueType = m._valueType;
1234 _interlacingType = m._interlacingType;
1238 _mesh->removeReference();
1241 _mesh->addReference();
1247 Initializes all the field values to \a value
1249 template <class T, class INTERLACING_TAG>
1250 FIELD<T, INTERLACING_TAG> & FIELD<T, INTERLACING_TAG>::operator=(T value)
1252 MESSAGE_MED("Appel de FIELD<T>::operator= T") ;
1253 int size=getNumberOfComponents()*getNumberOfValues();
1254 T* ptr= const_cast<T*>( getValue());
1255 for (int i=0; i< size; i++)
1261 /*!\addtogroup FIELD_algo
1266 Overload addition operator.
1267 This operation is authorized only for compatible fields that have the same support.
1268 The compatibility checking includes equality tests of the folowing data members:\n
1270 - _numberOfComponents
1273 - _MEDComponentsUnits.
1275 The data members of the returned field are initialized, based on the first field, except for the name,
1276 which is the combination of the two field's names and the operator.
1277 Advised Utilisation in C++ : <tt> FIELD<T> c = a + b; </tt> \n
1278 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1279 When using python, this operator calls the copy constructor in any case.
1280 The user has to be aware that when using operator + in associatives expressions like
1281 <tt> a = b + c + d +e; </tt> \n
1282 no optimisation is performed : the evaluation of last expression requires the construction of
1285 template <class T, class INTERLACING_TAG>
1286 FIELD<T, INTERLACING_TAG> *FIELD<T, INTERLACING_TAG>::operator+(const FIELD & m) const
1288 const char* LOC = "FIELD<T>::operator+(const FIELD & m)";
1290 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1292 // Creation of the result - memory is allocated by FIELD constructor
1293 FIELD<T, INTERLACING_TAG> *result=new FIELD<T, INTERLACING_TAG>(this->getSupport(),this->getNumberOfComponents());
1294 result->_operationInitialize(*this,m,"+"); // perform Atribute's initialization
1295 result->_add_in_place(*this,m); // perform addition
1301 /*! Overloaded Operator +=
1302 * Operations are directly performed in the first field's array.
1303 * This operation is authorized only for compatible fields that have the same support.
1305 template <class T, class INTERLACING_TAG>
1306 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator+=(const FIELD & m)
1308 const char* LOC = "FIELD<T>::operator+=(const FIELD & m)";
1310 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1312 const T* value1=m.getValue(); // get pointers to the values we are adding
1314 // get a non const pointer to the inside array of values and perform operation
1315 T * value=const_cast<T *> (getValue());
1316 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1317 const T* endV=value+size; // pointer to the end of value
1318 for(;value!=endV; value1++,value++)
1325 /*! Addition of fields. Static member function.
1326 * The function return a pointer to a new created field that holds the addition.
1327 * Data members are checked for compatibility and initialized.
1328 * The user is in charge of memory deallocation.
1330 template <class T, class INTERLACING_TAG>
1331 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::add(const FIELD& m, const FIELD& n)
1333 const char* LOC = "FIELD<T>::add(const FIELD & m, const FIELD& n)";
1335 FIELD_::_checkFieldCompatibility(m, n); // may throw exception
1337 // Creation of a new field
1338 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1339 m.getNumberOfComponents());
1340 result->_operationInitialize(m,n,"+"); // perform Atribute's initialization
1341 result->_add_in_place(m,n); // perform addition
1347 /*! Same as add method except that field check is deeper.
1349 template <class T, class INTERLACING_TAG>
1350 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::addDeep(const FIELD& m, const FIELD& n)
1352 const char* LOC = "FIELD<T>::addDeep(const FIELD & m, const FIELD& n)";
1354 FIELD_::_deepCheckFieldCompatibility(m, n); // may throw exception
1356 // Creation of a new field
1357 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1358 m.getNumberOfComponents());
1359 result->_operationInitialize(m,n,"+"); // perform Atribute's initialization
1360 result->_add_in_place(m,n); // perform addition
1367 Overload substraction operator.
1368 This operation is authorized only for compatible fields that have the same support.
1369 The compatibility checking includes equality tests of the folowing data members:\n
1371 - _numberOfComponents
1374 - _MEDComponentsUnits.
1376 The data members of the returned field are initialized, based on the first field, except for the name,
1377 which is the combination of the two field's names and the operator.
1378 Advised Utilisation in C++ : <tt> FIELD<T> c = a - b; </tt> \n
1379 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1380 When using python, this operator calls the copy constructor in any case.
1381 The user has to be aware that when using operator - in associatives expressions like
1382 <tt> a = b - c - d -e; </tt> \n
1383 no optimisation is performed : the evaluation of last expression requires the construction of
1386 template <class T, class INTERLACING_TAG>
1387 FIELD<T, INTERLACING_TAG> *FIELD<T, INTERLACING_TAG>::operator-(const FIELD & m) const
1389 const char* LOC = "FIELD<T>::operator-(const FIELD & m)";
1391 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1393 // Creation of the result - memory is allocated by FIELD constructor
1394 FIELD<T, INTERLACING_TAG> *result=new FIELD<T, INTERLACING_TAG>(this->getSupport(),this->getNumberOfComponents());
1395 result->_operationInitialize(*this,m,"-"); // perform Atribute's initialization
1396 result->_sub_in_place(*this,m); // perform substracion
1402 template <class T, class INTERLACING_TAG>
1403 FIELD<T, INTERLACING_TAG> *FIELD<T, INTERLACING_TAG>::operator-() const
1405 const char* LOC = "FIELD<T>::operator-()";
1408 // Creation of the result - memory is allocated by FIELD constructor
1409 FIELD<T, INTERLACING_TAG> *result=new FIELD<T, INTERLACING_TAG>(this->getSupport(),this->getNumberOfComponents());
1410 // Atribute's initialization
1411 result->setName("- "+getName());
1412 result->setComponentsNames(getComponentsNames());
1413 // not yet implemented setComponentType(getComponentType());
1414 result->setComponentsDescriptions(getComponentsDescriptions());
1415 result->setMEDComponentsUnits(getMEDComponentsUnits());
1416 result->setComponentsUnits(getComponentsUnits());
1417 result->setIterationNumber(getIterationNumber());
1418 result->setTime(getTime());
1419 result->setOrderNumber(getOrderNumber());
1421 const T* value1=getValue();
1422 // get a non const pointer to the inside array of values and perform operation
1423 T * value=const_cast<T *> (result->getValue());
1424 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1425 const T* endV=value+size; // pointer to the end of value
1427 for(;value!=endV; value1++,value++)
1428 *value = -(*value1);
1433 /*! Overloaded Operator -=
1434 * Operations are directly performed in the first field's array.
1435 * This operation is authorized only for compatible fields that have the same support.
1437 template <class T, class INTERLACING_TAG>
1438 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator-=(const FIELD & m)
1440 const char* LOC = "FIELD<T>::operator-=(const FIELD & m)";
1442 FIELD_::_checkFieldCompatibility(*this, m); // may throw exception
1444 const T* value1=m.getValue();
1446 // get a non const pointer to the inside array of values and perform operation
1447 T * value=const_cast<T *> (getValue());
1448 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1449 const T* endV=value+size; // pointer to the end of value
1451 for(;value!=endV; value1++,value++)
1460 /*! Apply to a given field component the linear function x -> ax+b.
1461 * calculation is done "in place".
1463 template <class T, class INTERLACIN_TAG> void FIELD<T, INTERLACIN_TAG>::applyLin(T a, T b, int icomp)
1465 // get a non const pointer to the inside array of values and perform operation in place
1466 T * value=const_cast<T *> (getValue());
1468 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1470 if (size>0) // for a negative size, there is nothing to do
1473 const T* lastvalue=value+size; // pointer to the end of value
1475 for(;value!=lastvalue; value+=getNumberOfComponents()) // apply linear transformation
1476 *value = a*(*value)+b;
1480 /*! Substraction of fields. Static member function.
1481 * The function return a pointer to a new created field that holds the substraction.
1482 * Data members are checked for compatibility and initialized.
1483 * The user is in charge of memory deallocation.
1485 template <class T, class INTERLACING_TAG>
1486 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::sub(const FIELD& m, const FIELD& n)
1488 const char* LOC = "FIELD<T>::sub(const FIELD & m, const FIELD& n)";
1490 FIELD_::_checkFieldCompatibility(m, n); // may throw exception
1492 // Creation of a new field
1493 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1494 m.getNumberOfComponents());
1495 result->_operationInitialize(m,n,"-"); // perform Atribute's initialization
1496 result->_sub_in_place(m,n); // perform substraction
1502 /*! Same as sub method except that field check is deeper.
1504 template <class T, class INTERLACING_TAG>
1505 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::subDeep(const FIELD& m, const FIELD& n)
1507 const char* LOC = "FIELD<T>::subDeep(const FIELD & m, const FIELD& n)";
1509 FIELD_::_deepCheckFieldCompatibility(m, n); // may throw exception
1511 // Creation of a new field
1512 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1513 m.getNumberOfComponents());
1514 result->_operationInitialize(m,n,"-"); // perform Atribute's initialization
1515 result->_sub_in_place(m,n); // perform substraction
1522 Overload multiplication operator.
1523 This operation is authorized only for compatible fields that have the same support.
1524 The compatibility checking includes equality tests of the folowing data members:\n
1526 - _numberOfComponents
1529 - _MEDComponentsUnits.
1531 The data members of the returned field are initialized, based on the first field, except for the name,
1532 which is the combination of the two field's names and the operator.
1533 Advised Utilisation in C++ : <tt> FIELD<T> c = a * b; </tt> \n
1534 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1535 When using python, this operator calls the copy constructor in any case.
1536 The user has to be aware that when using operator * in associatives expressions like
1537 <tt> a = b * c * d *e; </tt> \n
1538 no optimisation is performed : the evaluation of last expression requires the construction of
1541 template <class T, class INTERLACING_TAG>
1542 FIELD<T, INTERLACING_TAG> *FIELD<T, INTERLACING_TAG>::operator*(const FIELD & m) const
1544 const char* LOC = "FIELD<T>::operator*(const FIELD & m)";
1546 FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1548 // Creation of the result - memory is allocated by FIELD constructor
1549 FIELD<T, INTERLACING_TAG> *result=new FIELD<T, INTERLACING_TAG>(this->getSupport(),this->getNumberOfComponents());
1550 result->_operationInitialize(*this,m,"*"); // perform Atribute's initialization
1551 result->_mul_in_place(*this,m); // perform multiplication
1557 /*! Overloaded Operator *=
1558 * Operations are directly performed in the first field's array.
1559 * This operation is authorized only for compatible fields that have the same support.
1561 template <class T, class INTERLACING_TAG>
1562 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator*=(const FIELD & m)
1564 const char* LOC = "FIELD<T>::operator*=(const FIELD & m)";
1566 FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1568 const T* value1=m.getValue();
1570 // get a non const pointer to the inside array of values and perform operation
1571 T * value=const_cast<T *> (getValue());
1572 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1573 const T* endV=value+size; // pointer to the end of value
1575 for(;value!=endV; value1++,value++)
1583 /*! Multiplication of fields. Static member function.
1584 * The function return a pointer to a new created field that holds the multiplication.
1585 * Data members are checked for compatibility and initialized.
1586 * The user is in charge of memory deallocation.
1588 template <class T, class INTERLACING_TAG>
1589 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::mul(const FIELD& m, const FIELD& n)
1591 const char* LOC = "FIELD<T>::mul(const FIELD & m, const FIELD& n)";
1593 FIELD_::_checkFieldCompatibility(m, n, false); // may throw exception
1595 // Creation of a new field
1596 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1597 m.getNumberOfComponents());
1598 result->_operationInitialize(m,n,"*"); // perform Atribute's initialization
1599 result->_mul_in_place(m,n); // perform multiplication
1605 /*! Same as mul method except that field check is deeper.
1607 template <class T, class INTERLACING_TAG>
1608 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::mulDeep(const FIELD& m, const FIELD& n)
1610 const char* LOC = "FIELD<T>::mulDeep(const FIELD & m, const FIELD& n)";
1612 FIELD_::_deepCheckFieldCompatibility(m, n, false); // may throw exception
1614 // Creation of a new field
1615 FIELD<T, INTERLACING_TAG>* result = new FIELD<T,INTERLACING_TAG>(m.getSupport(),
1616 m.getNumberOfComponents());
1617 result->_operationInitialize(m,n,"*"); // perform Atribute's initialization
1618 result->_mul_in_place(m,n); // perform multiplication
1625 Overload division operator.
1626 This operation is authorized only for compatible fields that have the same support.
1627 The compatibility checking includes equality tests of the folowing data members:\n
1629 - _numberOfComponents
1632 - _MEDComponentsUnits.
1634 The data members of the returned field are initialized, based on the first field, except for the name,
1635 which is the combination of the two field's names and the operator.
1636 Advised Utilisation in C++ : <tt> FIELD<T> c = a / b; </tt> \n
1637 In this case, the (recent) compilators perform optimisation and don't call the copy constructor.
1638 When using python, this operator calls the copy constructor in any case.
1639 The user has to be aware that when using operator / in associatives expressions like
1640 <tt> a = b / c / d /e; </tt> \n
1641 no optimisation is performed : the evaluation of last expression requires the construction of
1644 template <class T, class INTERLACING_TAG>
1645 FIELD<T, INTERLACING_TAG> *FIELD<T, INTERLACING_TAG>::operator/(const FIELD & m) const
1647 const char* LOC = "FIELD<T>::operator/(const FIELD & m)";
1649 FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1651 // Creation of the result - memory is allocated by FIELD constructor
1652 FIELD<T, INTERLACING_TAG> *result=new FIELD<T, INTERLACING_TAG>(this->getSupport(),this->getNumberOfComponents());
1655 result->_operationInitialize(*this,m,"/"); // perform Atribute's initialization
1656 result->_div_in_place(*this,m); // perform division
1658 catch(MEDEXCEPTION& e)
1660 result->removeReference();
1669 /*! Overloaded Operator /=
1670 * Operations are directly performed in the first field's array.
1671 * This operation is authorized only for compatible fields that have the same support.
1673 template <class T, class INTERLACING_TAG>
1674 FIELD<T, INTERLACING_TAG>& FIELD<T, INTERLACING_TAG>::operator/=(const FIELD & m)
1676 const char* LOC = "FIELD<T>::operator/=(const FIELD & m)";
1678 FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception
1680 const T* value1=m.getValue(); // get pointers to the values we are adding
1682 // get a non const pointer to the inside array of values and perform operation
1683 T * value=const_cast<T *> (getValue());
1684 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
1685 const T* endV=value+size; // pointer to the end of value
1687 for(;value!=endV; value1++,value++)
1695 /*! Division of fields. Static member function.
1696 * The function return a pointer to a new created field that holds the division.
1697 * Data members are checked for compatibility and initialized.
1698 * The user is in charge of memory deallocation.
1700 template <class T, class INTERLACING_TAG>
1701 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::div(const FIELD& m, const FIELD& n)
1703 const char* LOC = "FIELD<T>::div(const FIELD & m, const FIELD& n)";
1705 FIELD_::_checkFieldCompatibility(m, n, false); // may throw exception
1707 // Creation of a new field
1708 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1709 m.getNumberOfComponents());
1712 result->_operationInitialize(m,n,"/"); // perform Atribute's initialization
1713 result->_div_in_place(m,n); // perform division
1715 catch(MEDEXCEPTION& e)
1717 result->removeReference();
1724 /*! Same as div method except that field check is deeper.
1726 template <class T,class INTERLACING_TAG>
1727 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::divDeep(const FIELD& m, const FIELD& n)
1729 const char* LOC = "FIELD<T>::divDeep(const FIELD & m, const FIELD& n)";
1731 FIELD_::_deepCheckFieldCompatibility(m, n, false); // may throw exception
1733 // Creation of a new field
1734 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),
1735 m.getNumberOfComponents());
1738 result->_operationInitialize(m,n,"/"); // perform Atribute's initialization
1739 result->_div_in_place(m,n); // perform division
1741 catch(MEDEXCEPTION& e)
1743 result->removeReference();
1757 This internal method initialize the members of a new field created to hold the result of the operation Op .
1758 Initialization is based on the first field, except for the name, which is the combination of the two field's names
1762 template <class T, class INTERLACING_TAG>
1763 void FIELD<T, INTERLACING_TAG>::_operationInitialize(const FIELD& m,const FIELD& n, const char* Op)
1765 MESSAGE_MED("Appel methode interne " << Op);
1767 // Atribute's initialization (copy of the first field's attributes)
1768 // Other data members (_support, _numberOfValues) are initialized in the field's constr.
1769 setName(m.getName()+" "+Op+" "+n.getName());
1770 setComponentsNames(m.getComponentsNames());
1771 setComponentsDescriptions(m.getComponentsDescriptions());
1772 setMEDComponentsUnits(m.getMEDComponentsUnits());
1774 // The following data member may differ from field m to n.
1775 // The initialization is done based on the first field.
1777 setComponentsUnits(m.getComponentsUnits());
1779 setIterationNumber(m.getIterationNumber());
1780 setTime(m.getTime());
1781 setOrderNumber(m.getOrderNumber());
1787 Internal method called by FIELD<T>::operator+ and FIELD<T>::add to perform addition "in place".
1788 This method is applied to a just created field with medModeSwitch mode.
1789 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1793 template <class T, class INTERLACING_TAG>
1794 void FIELD<T, INTERLACING_TAG>::_add_in_place(const FIELD& m,const FIELD& n)
1796 // get pointers to the values we are adding
1797 const T* value1=m.getValue();
1798 const T* value2=n.getValue();
1799 // get a non const pointer to the inside array of values and perform operation
1800 T * value=const_cast<T *> (getValue());
1802 const int size=getNumberOfValues()*getNumberOfComponents();
1804 const T* endV1=value1+size;
1805 for(;value1!=endV1; value1++,value2++,value++)
1806 *value=(*value1)+(*value2);
1811 Internal method called by FIELD<T>::operator- and FIELD<T>::sub to perform substraction "in place".
1812 This method is applied to a just created field with medModeSwitch mode.
1813 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1817 template <class T, class INTERLACING_TAG>
1818 void FIELD<T, INTERLACING_TAG>::_sub_in_place(const FIELD& m,const FIELD& n)
1820 // get pointers to the values we are adding
1821 const T* value1=m.getValue();
1822 const T* value2=n.getValue();
1823 // get a non const pointer to the inside array of values and perform operation
1824 T * value=const_cast<T *> (getValue());
1826 const int size=getNumberOfValues()*getNumberOfComponents();
1828 const T* endV1=value1+size;
1829 for(;value1!=endV1; value1++,value2++,value++)
1830 *value=(*value1)-(*value2);
1835 Internal method called by FIELD<T>::operator* and FIELD<T>::mul to perform multiplication "in place".
1836 This method is applied to a just created field with medModeSwitch mode.
1837 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1841 template <class T, class INTERLACING_TAG>
1842 void FIELD<T, INTERLACING_TAG>::_mul_in_place(const FIELD& m,const FIELD& n)
1844 // get pointers to the values we are adding
1845 const T* value1=m.getValue();
1846 const T* value2=n.getValue();
1847 // get a non const pointer to the inside array of values and perform operation
1848 T * value=const_cast<T *> (getValue());
1850 const int size=getNumberOfValues()*getNumberOfComponents();
1852 const T* endV1=value1+size;
1853 for(;value1!=endV1; value1++,value2++,value++)
1854 *value=(*value1)*(*value2);
1859 Internal method called by FIELD<T>::operator/ and FIELD<T>::div to perform division "in place".
1860 This method is applied to a just created field with medModeSwitch mode.
1861 For this reason, the alternate mode doesn't need to be set to 0 after performing operation :
1865 template <class T, class INTERLACING_TAG>
1866 void FIELD<T, INTERLACING_TAG>::_div_in_place(const FIELD& m,const FIELD& n) throw (MEDEXCEPTION)
1868 // get pointers to the values we are adding
1869 const T* value1=m.getValue();
1870 const T* value2=n.getValue();
1871 // get a non const pointer to the inside array of values and perform operation
1872 T * value=const_cast<T *> (getValue());
1874 const int size=getNumberOfValues()*getNumberOfComponents();
1876 const T* endV1=value1+size;
1877 for(;value1!=endV1; value1++,value2++,value++){
1878 if ( *value2 == 0 ) { // FAIRE PLUTOT UN TRY CATCH Rmq from EF
1880 diagnosis="FIELD<T,INTERLACING_TAG>::_div_in_place(...) : Divide by zero !";
1881 throw MEDEXCEPTION(diagnosis.c_str());
1883 *value=(*value1)/(*value2);
1888 \addtogroup FIELD_algo
1892 /*! Return maximum of all absolute values contained in the array (all elements and all components are browsed).
1894 template <class T, class INTERLACIN_TAG> double FIELD<T, INTERLACIN_TAG>::normMax() const throw (MEDEXCEPTION)
1896 const T* value=getValue(); // get pointer to the values
1897 const int size=getNumberOfValues()*getNumberOfComponents();
1898 if (size <= 0) // Size of array has to be strictly positive
1901 diagnosis="FIELD<T,INTERLACIN_TAG>::normMax() : cannot compute the norm of "+getName()+
1902 " : it size is non positive!";
1903 throw MEDEXCEPTION(diagnosis.c_str());
1905 const T* lastvalue=value+size; // get pointer just after last value
1906 const T* pMax=value; // pointer to the max value
1907 const T* pMin=value; // pointer to the min value
1909 // get pointers to the max & min value of array
1910 while ( ++value != lastvalue )
1912 if ( *pMin > *value )
1914 if ( *pMax < *value )
1918 T Max= *pMax>(T) 0 ? *pMax : -*pMax; // Max=abs(*pMax)
1919 T Min= *pMin>(T) 0 ? *pMin : -*pMin; // Min=abs(*pMin)
1921 return Max>Min ? double(Max) : double(Min);
1924 /*! Return Euclidian norm for all elements of the array.
1926 template <class T, class INTERLACIN_TAG> double FIELD<T, INTERLACIN_TAG>::norm2() const throw (MEDEXCEPTION)
1928 const T* value=this->getValue(); // get const pointer to the values
1929 const int size=getNumberOfValues()*getNumberOfComponents(); // get size of array
1930 if (size <= 0) // Size of array has to be strictly positive
1933 diagnosis="FIELD<T,INTERLACIN_TAG>::norm2() : cannot compute the norm of "+getName()+
1934 " : it size is non positive!";
1935 throw MEDEXCEPTION(diagnosis.c_str());
1937 const T* lastvalue=value+size; // point just after last value
1939 T result((T)0); // init
1940 for( ; value!=lastvalue ; ++value)
1941 result += (*value) * (*value);
1943 return std::sqrt(double(result));
1947 //------------- TDG and BS addings
1949 /*! Return Extrema of field
1951 template <class T, class INTERLACIN_TAG> void FIELD<T, INTERLACIN_TAG>::getMinMax(T &vmin, T &vmax) throw (MEDEXCEPTION)
1953 const T* value=getValue(); // get pointer to the values
1954 const int size=getNumberOfValues()*getNumberOfComponents();
1955 const T* lastvalue=value+size; // point just after last value
1957 if (size <= 0){ // Size of array has to be strictly positive
1960 diagnosis="FIELD<T,INTERLACIN_TAG>::getMinMax() : cannot compute the extremums of "+getName()+
1961 " : its size is non positive!";
1962 throw MEDEXCEPTION(diagnosis.c_str());
1966 vmax=MinMax<T>::getMin(); // init a max value
1967 vmin=MinMax<T>::getMax(); // init a min value
1969 for( ; value!=lastvalue ; ++value){
1970 if ( vmin > *value )
1972 if ( vmax < *value )
1986 /*! Return Histogram of field
1988 template <class T, class INTERLACIN_TAG> vector<int> FIELD<T, INTERLACIN_TAG>::getHistogram(int &nbint) throw (MEDEXCEPTION)
1990 const T* value=getValue(); // get pointer to the values
1991 const int size=getNumberOfValues()*getNumberOfComponents();
1992 const T* lastvalue=value+size; // point just after last value
1994 if (size <= 0){ // Size of array has to be strictly positive
1997 diagnosis="FIELD<T,INTERLACIN_TAG>::getHistogram() : cannot compute the histogram of "+getName()+
1998 " : it size is non positive!";
1999 throw MEDEXCEPTION(diagnosis.c_str());
2002 vector<int> Histogram(nbint) ;
2006 for( j=0 ; j!=nbint ; j++) Histogram[j]=0 ;
2008 getMinMax(vmin,vmax);
2009 for( ; value!=lastvalue ; ++value){
2010 if(*value==vmax) j = nbint-1;
2011 else j = (int)(((double)nbint * (*value-vmin))/(vmax-vmin));
2019 /*! Return vectorial gradient field
2021 template <class T, class INTERLACIN_TAG>
2022 FIELD<double, FullInterlace>* FIELD<T, INTERLACIN_TAG>::buildGradient() const throw (MEDEXCEPTION)
2024 const char * LOC = "FIELD<T, INTERLACIN_TAG>::buildGradient() : ";
2027 // space dimension of input mesh
2028 int spaceDim = getSupport()->getMesh()->getSpaceDimension();
2029 double *x = new double[spaceDim];
2031 FIELD<double, FullInterlace>* Gradient =
2032 new FIELD<double, FullInterlace>(getSupport(),spaceDim);
2034 string name("gradient of ");
2036 Gradient->setName(name);
2037 string descr("gradient of ");
2038 descr += getDescription();
2039 Gradient->setDescription(descr);
2041 if( _numberOfComponents > 1 ){
2044 throw MEDEXCEPTION("gradient calculation only on scalar field");
2047 for(int i=1;i<=spaceDim;i++){
2048 string nameC("gradient of ");
2050 Gradient->setComponentName(i,nameC);
2051 Gradient->setComponentDescription(i,"gradient");
2052 string MEDComponentUnit = getMEDComponentUnit(1)+getSupport()->getMesh()->getCoordinatesUnits()[i-1];
2053 Gradient->setMEDComponentUnit(i,MEDComponentUnit);
2056 Gradient->setIterationNumber(getIterationNumber());
2057 Gradient->setOrderNumber(getOrderNumber());
2058 Gradient->setTime(getTime());
2060 // typ of entity on what is field
2061 MED_EN::medEntityMesh typ = getSupport()->getEntity();
2067 const double *coord;
2075 // read connectivity array to have the list of nodes contained by an element
2076 C = getSupport()->getMesh()->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,typ,MED_ALL_ELEMENTS);
2077 iC = getSupport()->getMesh()->getConnectivityIndex(MED_NODAL,typ);
2078 // calculate reverse connectivity to have the list of elements which contains node i
2079 revC = getSupport()->getMesh()->getReverseConnectivity(MED_NODAL,typ);
2080 indC = getSupport()->getMesh()->getReverseConnectivityIndex(MED_NODAL,typ);
2081 // coordinates of each node
2082 coord = getSupport()->getMesh()->getCoordinates(MED_FULL_INTERLACE);
2083 // number of elements
2084 NumberOf = getSupport()->getNumberOfElements(MED_ALL_ELEMENTS);
2085 // barycenter field of elements
2086 FIELD<double, FullInterlace>* barycenter = getSupport()->getMesh()->getBarycenter(getSupport());
2088 // calculate gradient vector for each element i
2089 for (int i = 1; i < NumberOf + 1; i++) {
2091 // listElements contains elements which contains a node of element i
2092 set <int> listElements;
2093 set <int>::iterator elemIt;
2094 listElements.clear();
2096 // for each node j of element i
2097 for (int ij = iC[i-1]; ij < iC[i]; ij++) {
2099 for (int k = indC[j-1]; k < indC[j]; k++) {
2100 // c element contains node j
2102 // we put the elements in set
2104 listElements.insert(c);
2107 // coordinates of barycentre of element i in space of dimension spaceDim
2108 for (int j = 0; j < spaceDim; j++)
2109 x[j] = barycenter->getValueIJ(i,j+1);
2111 for (int j = 0; j < spaceDim; j++) {
2112 // value of field of element i
2113 double val = getValueIJ(i,1);
2115 // calculate gradient for each neighbor element
2116 for (elemIt = listElements.begin(); elemIt != listElements.end(); elemIt++) {
2119 for (int l = 0; l < spaceDim; l++) {
2120 // coordinate of barycenter of element elem
2121 double xx = barycenter->getValueIJ(elem, l+1);
2122 d2 += (x[l]-xx) * (x[l]-xx);
2124 grad += (barycenter->getValueIJ(elem,j+1)-x[j])*(getValueIJ(elem,1)-val)/sqrt(d2);
2126 if (listElements.size() != 0) grad /= listElements.size();
2127 Gradient->setValueIJ(i,j+1,grad);
2134 // read connectivity array to have the list of nodes contained by an element
2135 C = getSupport()->getMesh()->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_ALL_ELEMENTS);
2136 iC = getSupport()->getMesh()->getConnectivityIndex(MED_NODAL,MED_CELL);
2137 // calculate reverse connectivity to have the list of elements which contains node i
2138 revC=getSupport()->getMesh()->getReverseConnectivity(MED_NODAL,MED_CELL);
2139 indC=getSupport()->getMesh()->getReverseConnectivityIndex(MED_NODAL,MED_CELL);
2140 // coordinates of each node
2141 coord = getSupport()->getMesh()->getCoordinates(MED_FULL_INTERLACE);
2143 // calculate gradient for each node
2144 NumberOf = getSupport()->getNumberOfElements(MED_ALL_ELEMENTS);
2145 for (int i=1; i<NumberOf+1; i++){
2146 // listNodes contains nodes neigbor of node i
2147 set <int> listNodes;
2148 set <int>::iterator nodeIt ;
2150 for(int j=indC[i-1];j<indC[i];j++){
2151 // c element contains node i
2153 // we put the nodes of c element in set
2154 for(int k=iC[c-1];k<iC[c];k++)
2156 listNodes.insert(C[k-1]);
2158 // coordinates of node i in space of dimension spaceDim
2159 for(int j=0;j<spaceDim;j++)
2160 x[j] = coord[(i-1)*spaceDim+j];
2162 for(int j=0;j<spaceDim;j++){
2164 double val = getValueIJ(i,1);
2166 // calculate gradient for each neighbor node
2167 for(nodeIt=listNodes.begin();nodeIt!=listNodes.end();nodeIt++){
2170 for(int l=0;l<spaceDim;l++){
2171 double xx = coord[(node-1)*spaceDim+l];
2172 d2 += (x[l]-xx) * (x[l]-xx);
2174 grad += (coord[(node-1)*spaceDim+j]-x[j])*(getValueIJ(node,1)-val)/sqrt(d2);
2176 if(listNodes.size() != 0) grad /= listNodes.size();
2177 Gradient->setValueIJ(i,j+1,grad);
2181 case MED_ALL_ENTITIES:
2184 throw MEDEXCEPTION("gradient calculation not yet implemented on all elements");
2194 /*! Return scalar norm2 field
2196 template <class T, class INTERLACIN_TAG>
2197 FIELD<double, FullInterlace>* FIELD<T, INTERLACIN_TAG>::buildNorm2Field() const throw (MEDEXCEPTION)
2199 const char * LOC = "FIELD<T, INTERLACIN_TAG>::buildNorm2Field() : ";
2202 FIELD<double, FullInterlace>* Norm2Field =
2203 new FIELD<double, FullInterlace>(getSupport(),1);
2205 string name("norm2 of ");
2207 Norm2Field->setName(name);
2208 string descr("norm2 of ");
2209 descr += getDescription();
2210 Norm2Field->setDescription(descr);
2212 string nameC("norm2 of ");
2214 Norm2Field->setComponentName(1,nameC);
2215 Norm2Field->setComponentDescription(1,"norm2");
2216 string MEDComponentUnit = getMEDComponentUnit(1);
2217 Norm2Field->setMEDComponentUnit(1,MEDComponentUnit);
2219 Norm2Field->setIterationNumber(getIterationNumber());
2220 Norm2Field->setOrderNumber(getOrderNumber());
2221 Norm2Field->setTime(getTime());
2223 // calculate nom2 for each element
2224 int NumberOf = getSupport()->getNumberOfElements(MED_ALL_ELEMENTS);
2225 for (int i=1; i<NumberOf+1; i++){
2227 for(int j=1;j<=getNumberOfComponents();j++)
2228 norm2 += getValueIJ(i,j)*getValueIJ(i,j);
2229 Norm2Field->setValueIJ(i,1,sqrt(norm2));
2237 /*! Apply to each (scalar) field component the template parameter T_function,
2238 * which is a pointer to function.
2239 * Since the pointer is known at compile time, the function is inlined into the inner loop!
2240 * calculation is done "in place".
2243 * \code myField.applyFunc<std::sqrt>(); // apply sqare root function \endcode
2244 * \code myField.applyFunc<myFunction>(); // apply your own created function \endcode
2246 template <class T, class INTERLACIN_TAG> template <T T_function(T)>
2247 void FIELD<T, INTERLACIN_TAG>::applyFunc()
2249 // get a non const pointer to the inside array of values and perform operation
2250 T * value=const_cast<T *> (getValue());
2251 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
2253 if (size>0) // for a negative size, there is nothing to do
2255 const T* lastvalue=value+size; // pointer to the end of value
2256 for(;value!=lastvalue; ++value) // apply linear transformation
2257 *value = T_function(*value);
2261 template <class T, class INTERLACIN_TAG> T FIELD<T, INTERLACIN_TAG>::pow(T x)
2263 return (T)::pow((double)x,FIELD<T, INTERLACIN_TAG>::_scalarForPow);
2266 /*! Apply to each (scalar) field component the math function pow.
2267 * calculation is done "in place".
2270 * \code myField.applyFunc<std::sqrt>(); // apply sqare root function \endcode
2271 * \code myField.applyFunc<myFunction>(); // apply your own created function \endcode
2273 template <class T, class INTERLACIN_TAG> void FIELD<T, INTERLACIN_TAG>::applyPow(T scalar)
2275 FIELD<T, INTERLACIN_TAG>::_scalarForPow=scalar;
2276 applyFunc<FIELD<T, INTERLACIN_TAG>::pow>();
2279 /*! Apply to each (scalar) field component the linear function x -> ax+b.
2280 * calculation is done "in place".
2282 template <class T, class INTERLACIN_TAG> void FIELD<T, INTERLACIN_TAG>::applyLin(T a, T b)
2284 // get a non const pointer to the inside array of values and perform operation in place
2285 T * value=const_cast<T *> (getValue());
2286 const int size=getNumberOfValues()*getNumberOfComponents(); // size of array
2288 if (size>0) // for a negative size, there is nothing to do
2290 const T* lastvalue=value+size; // pointer to the end of value
2291 for(;value!=lastvalue; ++value) // apply linear transformation
2292 *value = a*(*value)+b;
2298 * Return a pointer to a new field that holds the scalar product. Static member function.
2299 * This operation is authorized only for compatible fields that have the same support.
2300 * The compatibility checking includes equality tests of the folowing data members:\n
2302 * - _numberOfComponents
2304 * - _componentsTypes
2305 * - _MEDComponentsUnits.
2306 * Data members are initialized.
2307 * The new field point to the same support and has one component.
2308 * Each value of it is the scalar product of the two argument's fields.
2309 * The user is in charge of memory deallocation.
2311 template <class T, class INTERLACING_TAG>
2312 FIELD<T, INTERLACING_TAG>*
2313 FIELD<T, INTERLACING_TAG>::scalarProduct(const FIELD & m, const FIELD & n, bool deepCheck)
2316 FIELD_::_checkFieldCompatibility( m, n, false); // may throw exception
2318 FIELD_::_deepCheckFieldCompatibility(m, n, false);
2320 // we need a MED_FULL_INTERLACE representation of m & n to compute the scalar product
2321 // result type imply INTERLACING_TAG=FullInterlace for m & n
2323 const int numberOfElements=m.getNumberOfValues(); // strictly positive
2324 const int NumberOfComponents=m.getNumberOfComponents(); // strictly positive
2326 // Creation & init of a the result field on the same support, with one component
2327 // You have to be careful about the interlacing mode, because in the computation step,
2328 // it seems to assume the the interlacing mode is the FullInterlacing
2330 FIELD<T, INTERLACING_TAG>* result = new FIELD<T, INTERLACING_TAG>(m.getSupport(),1);
2331 result->setName( "scalarProduct ( " + m.getName() + " , " + n.getName() + " )" );
2332 result->setIterationNumber(m.getIterationNumber());
2333 result->setTime(m.getTime());
2334 result->setOrderNumber(m.getOrderNumber());
2336 const T* value1=m.getValue(); // get const pointer to the values
2337 const T* value2=n.getValue(); // get const pointer to the values
2338 // get a non const pointer to the inside array of values and perform operation
2339 T * value=const_cast<T *> (result->getValue());
2341 const T* lastvalue=value+numberOfElements; // pointing just after last value of result
2342 for ( ; value!=lastvalue ; ++value ) // loop on all elements
2344 *value=(T)0; // initialize value
2345 const T* endofRow=value1+NumberOfComponents; // pointing just after end of row
2346 for ( ; value1 != endofRow; ++value1, ++value2) // computation of dot product
2347 *value += (*value1) * (*value2);
2352 /*! Return L2 Norm of the field's component.
2353 * Cannot be applied to a field with a support on nodes.
2354 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
2355 * For the nodal field, p_field_volume must be for all cells even if the field is partial.
2357 template <class T, class INTERLACING_TAG>
2358 double FIELD<T, INTERLACING_TAG>::normL2(int component,
2359 const FIELD<double, FullInterlace> * p_field_volume) const
2361 _checkNormCompatibility(p_field_volume, /*nodalAllowed=*/true); // may throw exception
2362 if ( component<1 || component>getNumberOfComponents() )
2363 throw MEDEXCEPTION(STRING("FIELD<T>::normL2() : The component argument should be between 1 and the number of components"));
2365 const FIELD<double, FullInterlace> * p_field_size=p_field_volume;
2366 if(!p_field_volume) // if the user don't supply the volume
2367 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
2369 p_field_size->addReference();
2370 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
2371 const double* vol=p_field_size->getValue();
2372 // Il n'est vraiment pas optimal de mixer des champs dans des modes d'entrelacement
2373 // different juste pour le calcul
2376 double integrale=0.0;
2379 if ( getSupport()->getEntity() == MED_NODE ) // issue 20120: [CEA 206] normL2 on NODE field
2381 //Most frequently the FIELD is on the whole mesh and
2382 // there is no need in optimizing iterations from supporting nodes-> back to cells,
2383 // so we iterate just on all cells
2384 const MESH * mesh = getSupport()->getMesh()->convertInMESH();
2385 const int nbCells = mesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS);
2386 const int *C = mesh->getConnectivity(MED_NODAL,MED_CELL,MED_ALL_ELEMENTS);
2387 const int *iC = mesh->getConnectivityIndex(MED_NODAL,MED_CELL);
2388 for (int i = 0; i < nbCells; ++i, ++vol) {
2389 // calculate integral on current element as average summ of values on all it's nodes
2390 double curCellValue = 0;
2391 try { // we expect exception with partial fields for nodes w/o values
2392 for (int ij = iC[i]; ij < iC[i+1]; ij++) {
2394 curCellValue += getValueIJ( node, component );
2397 catch ( MEDEXCEPTION ) {
2400 int nbNodes = iC[i+1]-iC[i];
2401 curCellValue /= nbNodes;
2402 integrale += (curCellValue * curCellValue) * std::abs(*vol);
2403 totVol+=std::abs(*vol);
2405 mesh->removeReference();
2409 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) {
2410 const T* value = getValue();
2411 value = value + (component-1) * getNumberOfValues();
2412 const T* lastvalue = value + getNumberOfValues(); // pointing just after the end of column
2413 for (; value!=lastvalue ; ++value ,++vol) {
2414 integrale += double((*value) * (*value)) * std::abs(*vol);
2415 totVol+=std::abs(*vol);
2418 else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
2419 ArrayNoByType* anArray = dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() );
2420 for (int i=1; i <= anArray->getNbElem() ; i++, ++vol ) {
2421 integrale += anArray->getIJ(i,component) * anArray->getIJ(i,component) * std::abs(*vol);
2422 totVol+=std::abs(*vol);
2425 else { // FULL_INTERLACE
2426 ArrayFull* anArray = dynamic_cast< ArrayFull * > ( getArrayNoGauss() );
2427 for (int i=1; i <= anArray->getNbElem() ; i++, ++vol ) {
2428 integrale += anArray->getIJ(i,component) * anArray->getIJ(i,component) * std::abs(*vol);
2429 totVol+=std::abs(*vol);
2435 p_field_size->removeReference(); // delete temporary volume field
2438 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
2439 return integrale/totVol;
2442 /*! Return L2 Norm of the field.
2443 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
2444 * For the nodal field, p_field_volume must be for all cells even if the field is partial.
2446 template <class T, class INTERLACING_TAG>
2447 double FIELD<T, INTERLACING_TAG>::normL2(const FIELD<double, FullInterlace> * p_field_volume) const
2449 _checkNormCompatibility(p_field_volume, /*nodalAllowed=*/true); // may throw exception
2450 const FIELD<double, FullInterlace> * p_field_size=p_field_volume;
2451 if(!p_field_volume) // if the user don't supply the volume
2452 p_field_size=_getFieldSize(); // we calculate the volume
2454 p_field_size->addReference();
2455 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
2456 const double* vol=p_field_size->getValue();
2457 const double* lastvol=vol+getNumberOfValues(); // pointing just after the end of vol
2460 double integrale=0.0;
2463 if ( getSupport()->getEntity() == MED_NODE ) // issue 20120: [CEA 206] normL2 on NODE field
2465 //Most frequently the FIELD is on the whole mesh and
2466 // there is no need in optimizing iterations from supporting nodes-> back to cells,
2467 // so we iterate just on all cells
2468 const MESH * mesh = getSupport()->getMesh()->convertInMESH();
2469 const int nbCells = mesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS);
2470 const int *C = mesh->getConnectivity(MED_NODAL,MED_CELL,MED_ALL_ELEMENTS);
2471 const int *iC = mesh->getConnectivityIndex(MED_NODAL,MED_CELL);
2472 int nbComp = getNumberOfComponents();
2473 for (int i = 0; i < nbCells; ++i, ++vol) {
2474 // calculate integral on current element as average summ of values on all it's nodes
2475 int nbNodes = iC[i+1]-iC[i];
2476 vector< double > curCellValue( nbComp, 0 );
2477 try { // we expect exception with partial fields for nodes w/o values
2478 for (int ij = iC[i]; ij < iC[i+1]; ij++) {
2480 for ( int j = 0; j < nbComp; ++j )
2481 curCellValue[ j ] += getValueIJ( node, j+1 ) / nbNodes;
2484 catch ( MEDEXCEPTION ) {
2488 for ( int j = 0; j < nbComp; ++j ) {
2489 integrale += (curCellValue[j] * curCellValue[j]) * std::abs(*vol);
2491 totVol+=std::abs(*vol);
2493 mesh->removeReference();
2494 if ( nbCells > 0 && totVol == 0.)
2495 throw MEDEXCEPTION("can't compute sobolev norm : "
2496 "none of elements has values on all it's nodes");
2500 const double* p_vol=vol;
2501 for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume
2502 totVol+=std::abs(*p_vol);
2504 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) {
2505 const T* value = getValue();
2506 for (int i=1; i<=getNumberOfComponents(); ++i) { // compute integral on all components
2507 for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol) {
2508 integrale += (*value) * (*value) * std::abs(*p_vol);
2512 else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
2513 ArrayNoByType* anArray = dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() );
2514 for (int j=1; j<=anArray->getDim(); j++) {
2516 for (p_vol=vol; i<=anArray->getNbElem() || p_vol!=lastvol; i++, ++p_vol ) {
2517 integrale += anArray->getIJ(i,j) * anArray->getIJ(i,j) * std::abs(*p_vol);
2521 else { // FULL_INTERLACE
2522 ArrayFull* anArray = dynamic_cast< ArrayFull * > ( getArrayNoGauss() );
2523 for (int j=1; j<=anArray->getDim(); j++) {
2525 for (p_vol=vol; i<=anArray->getNbElem() || p_vol!=lastvol; i++, ++p_vol ) {
2526 integrale += anArray->getIJ(i,j) * anArray->getIJ(i,j) * std::abs(*p_vol);
2532 p_field_size->removeReference(); // delete temporary volume field
2535 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
2536 return integrale/totVol;
2539 /*! Return L1 Norm of the field's component.
2540 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
2542 template <class T, class INTERLACING_TAG>
2543 double FIELD<T, INTERLACING_TAG>::normL1(int component,
2544 const FIELD<double, FullInterlace > * p_field_volume) const
2546 _checkNormCompatibility(p_field_volume); // may throw exception
2547 if ( component<1 || component>getNumberOfComponents() )
2548 throw MEDEXCEPTION(STRING("FIELD<T,INTERLACING_TAG>::normL1() : The component argument should be between 1 and the number of components"));
2550 const FIELD<double,FullInterlace> * p_field_size=p_field_volume;
2551 if(!p_field_volume) // if the user don't supply the volume
2552 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implÃÃÅ mentation dans mesh]
2554 p_field_size->addReference();
2555 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
2556 const double* vol = p_field_size->getValue();
2558 double integrale=0.0;
2561 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) {
2562 const T* value = getValue();
2563 const T* lastvalue = value + getNumberOfValues(); // pointing just after the end of column
2564 for (; value!=lastvalue ; ++value ,++vol) {
2565 integrale += std::abs( *value * *vol );
2566 totVol+=std::abs(*vol);
2569 else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
2570 ArrayNoByType* anArray = dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() );
2571 for (int i=1; i <= anArray->getNbElem() ; i++, ++vol ) {
2572 integrale += std::abs( anArray->getIJ(i,component) * (*vol));
2573 totVol+=std::abs(*vol);
2576 else { // FULL_INTERLACE
2577 ArrayFull* anArray = dynamic_cast< ArrayFull * > ( getArrayNoGauss() );
2578 for (int i=1; i <= anArray->getNbElem() ; i++, ++vol ) {
2579 integrale += std::abs( anArray->getIJ(i,component) * *vol);
2580 totVol+=std::abs(*vol);
2585 p_field_size->removeReference(); // delete temporary volume field
2587 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
2588 return integrale/totVol;
2591 /*! Return L1 Norm of the field.
2592 * Cannot be applied to a field with a support on nodes.
2593 * If the optional p_field_volume argument is furnished, the volume is not re-calculated.
2595 template <class T, class INTERLACING_TAG>
2596 double FIELD<T, INTERLACING_TAG>::normL1(const FIELD<double, FullInterlace> * p_field_volume) const
2598 _checkNormCompatibility(p_field_volume); // may throw exception
2599 const FIELD<double, FullInterlace> * p_field_size=p_field_volume;
2600 if(!p_field_volume) // if the user don't supply the volume
2601 p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh]
2603 p_field_size->addReference();
2604 // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size
2605 const double* vol = p_field_size->getValue();
2606 const double* lastvol = vol+getNumberOfValues(); // pointing just after the end of vol
2608 double integrale=0.0;
2610 const double* p_vol=vol;
2611 for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume
2612 totVol+=std::abs(*p_vol);
2614 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) {
2615 const T* value = getValue();
2616 for (int i=1; i<=getNumberOfComponents(); ++i) { // compute integral on all components
2617 for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol) {
2618 integrale += std::abs( *value * *p_vol );
2622 else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
2623 ArrayNoByType* anArray = dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() );
2624 for (int j=1; j<=anArray->getDim(); j++) {
2626 for (p_vol=vol; i<=anArray->getNbElem() || p_vol!=lastvol; i++, ++p_vol ) {
2627 integrale += std::abs( anArray->getIJ(i,j) * *p_vol );
2631 else { // FULL_INTERLACE
2632 ArrayFull* anArray = dynamic_cast< ArrayFull * > ( getArrayNoGauss() );
2633 for (int j=1; j<=anArray->getDim(); j++) {
2635 for (p_vol=vol; i<=anArray->getNbElem() || p_vol!=lastvol; i++, ++p_vol ) {
2636 integrale += std::abs( anArray->getIJ(i,j) * *p_vol );
2641 p_field_size->removeReference();
2643 throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
2644 return integrale/totVol;
2648 * \brief Return integral of the field.
2649 * \param subSupport - optional part of a field to consider.
2650 * \retval double - value of integral
2652 template <class T, class INTERLACING_TAG>
2653 double FIELD<T, INTERLACING_TAG>::integral(const SUPPORT *subSupport) const throw (MEDEXCEPTION)
2655 const char* LOC = "FIELD<>::integral(subSupport): ";
2657 double integrale = 0;
2659 if (!subSupport ) subSupport = _support;
2661 // check feasibility
2662 if ( getGaussPresence() )
2663 throw MEDEXCEPTION(STRING(LOC)<<"Gauss numbers greater than one are not yet implemented!");
2664 if ( subSupport->getEntity() != _support->getEntity())
2665 throw MEDEXCEPTION(STRING(LOC)<<"Different support entity of this field and subSupport");
2666 if ( subSupport->getEntity() == MED_EN::MED_NODE )
2667 throw MEDEXCEPTION(STRING(LOC)<<"Integral of nodal field not yet supported");
2670 const int nbElems = subSupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
2671 const bool subOnAll = ( subSupport->isOnAllElements() );
2672 const bool myOnAll = ( _support->isOnAllElements() );
2673 const int* subNums = !subOnAll ? subSupport->getNumber(MED_EN::MED_ALL_ELEMENTS) : 0;
2674 const int* myNums = !myOnAll ? _support->getNumber(MED_EN::MED_ALL_ELEMENTS) : 0;
2675 if ( !subOnAll && !subNums )
2676 throw MEDEXCEPTION(STRING(LOC)<<"Invalid support: no element numbers");
2677 if ( !myOnAll && !myNums )
2678 throw MEDEXCEPTION(STRING(LOC)<<"Invalid field support: no element numbers");
2679 if ( subOnAll && !myOnAll )
2680 return integral(NULL);
2682 // get size of elements
2683 const FIELD<double, FullInterlace> * cellSize=_getFieldSize(subSupport);
2684 const double* size = cellSize->getValue();
2685 const double* lastSize = size + nbElems; // pointing just after the end of size
2687 const T* value = getValue();
2689 // calculate integrale
2690 if ( (subOnAll && _support->isOnAllElements()) || subSupport == _support )
2692 const double* p_vol;
2693 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
2695 for (int j=1; j<=getNumberOfComponents(); ++j)
2696 for ( p_vol=size; p_vol != lastSize; ++value ,++p_vol)
2697 integrale += std::abs( *value * *p_vol );
2699 else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE )
2701 typename ArrayNoByType::InterlacingPolicy* indexer =
2702 dynamic_cast< typename ArrayNoByType::InterlacingPolicy * > ( getArrayNoGauss() );
2703 for (int i, j=1; j<=getNumberOfComponents(); j++)
2704 for (i = 1, p_vol=size; p_vol!=lastSize; i++, ++p_vol )
2705 integrale += std::abs( value[indexer->getIndex(i,j)] * *p_vol );
2707 else // FULL_INTERLACE
2709 for ( p_vol=size; p_vol != lastSize; ++p_vol)
2710 for (int j=0; j<getNumberOfComponents(); ++j, ++value)
2711 integrale += std::abs( *value * *p_vol );
2716 // find index for each element of subSupport
2717 PointerOf<int> index;
2718 if ( _support->isOnAllElements() )
2720 index.set( subNums );
2722 else // find common of two partial supports
2724 // hope that numbers are in increasing order
2725 index.set( nbElems );
2726 for (int ii = 0; ii < nbElems; ii++)
2728 bool allNumsFound = true;
2729 int i = 0, iSub = 0;
2730 for ( ; iSub < nbElems; ++iSub )
2732 while ( i < getNumberOfValues() && subNums[iSub] > myNums[i] )
2734 if (i == getNumberOfValues() /*subNums[iSub] > myNums[i]*/) // no more myNums
2736 index[iSub] = 0; // no such number in myNums
2739 else if ( subNums[iSub] == myNums[i] ) // elem number found
2740 index[iSub] = ++i; // -- index counts from 1
2741 else // subNums[iSub] < myNums[i]
2742 allNumsFound = (index[iSub] = 0); // no such number in myNums
2744 if ( iSub != nbElems || !allNumsFound )
2746 // check if numbers are in increasing order
2747 bool increasingOrder = true;
2748 for ( iSub = 1; iSub < nbElems && increasingOrder; ++iSub )
2749 increasingOrder = ( subNums[iSub-1] < subNums[iSub] );
2750 for ( i = 1; i < getNumberOfValues() && increasingOrder; ++i )
2751 increasingOrder = ( myNums[i-1] < myNums[i] );
2753 if ( !increasingOrder )
2754 for ( iSub = 0; iSub < nbElems; ++iSub )
2757 index[iSub] = _support->getValIndFromGlobalNumber( subNums[iSub] );
2759 catch (MEDEXCEPTION)
2767 if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
2769 for (int j=0; j<getNumberOfComponents(); ++j)
2771 value = getValue() + j * getNumberOfValues();
2772 for ( int i = 0; i < nbElems; ++i )
2774 integrale += std::abs( value[ index[i]-1 ] * size[i] );
2777 else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE )
2779 typename ArrayNoByType::InterlacingPolicy* indexer =
2780 dynamic_cast< typename ArrayNoByType::InterlacingPolicy * > ( getArrayNoGauss() );
2781 for (int j=1; j<=getNumberOfComponents(); j++)
2782 for ( int i = 0; i < nbElems; ++i )
2784 integrale += std::abs( value[indexer->getIndex(index[i],j)] * size[i] );
2786 else // FULL_INTERLACE
2788 const int dim = getNumberOfComponents();
2789 for ( int i = 0; i < nbElems; ++i )
2791 for (int j=0; j<dim; ++j)
2792 integrale += std::abs( value[ dim*(index[i]-1) + j] * size[i] );
2795 cellSize->removeReference();
2799 /*! Return a new field (to deallocate with delete) lying on subSupport that is included by
2800 * this->_support with corresponding values extracting from this->_value.
2802 template <class T, class INTERLACING_TAG>
2803 FIELD<T, INTERLACING_TAG>* FIELD<T, INTERLACING_TAG>::extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION)
2805 if(!subSupport->belongsTo(*_support))
2806 throw MEDEXCEPTION("FIELD<T>::extract : subSupport not included in this->_support !");
2807 if(_support->isOnAllElements() && subSupport->isOnAllElements())
2808 return new FIELD<T, INTERLACING_TAG>(*this);
2810 FIELD<T, INTERLACING_TAG> *ret = new FIELD<T, INTERLACING_TAG>(subSupport,
2811 _numberOfComponents);
2814 throw MEDEXCEPTION("FIELD<T>::extract : invalid support detected !");
2816 T* valuesToSet=(T*)ret->getValue();
2818 int nbOfEltsSub=subSupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
2819 const int *eltsSub=subSupport->getNumber(MED_EN::MED_ALL_ELEMENTS);
2820 T* tempVals=new T[_numberOfComponents];
2821 for(int i=0;i<nbOfEltsSub;i++)
2823 if(!getValueOnElement(eltsSub[i],tempVals))
2824 throw MEDEXCEPTION("Problem in belongsTo function !!!");
2825 for(int j=0;j<_numberOfComponents;j++)
2826 valuesToSet[i*_numberOfComponents+j]=tempVals[j];
2830 ret->copyGlobalInfo(*this);
2838 \addtogroup FIELD_io
2842 Constructor with parameters; the object is set via a file and its associated
2843 driver. For the moment only the MED_DRIVER is considered and if the last two
2844 argument (iterationNumber and orderNumber) are not set; their default value
2845 is -1. If the field fieldDriverName with the iteration number
2846 iterationNumber and the order number orderNumber does not exist in the file
2847 fieldDriverName; the constructor raises an exception.
2849 template <class T, class INTERLACING_TAG>
2850 FIELD<T, INTERLACING_TAG>::FIELD(const SUPPORT * Support,
2851 driverTypes driverType,
2852 const string & fileName/*=""*/,
2853 const string & fieldDriverName/*=""*/,
2854 const int iterationNumber,
2855 const int orderNumber) throw (MEDEXCEPTION)
2857 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) : ";
2864 _mesh = ( MESH* ) NULL;
2866 //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
2867 ASSERT_MED(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE)
2868 FIELD_::_valueType=SET_VALUE_TYPE<T>::_valueType;
2870 //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
2871 ASSERT_MED(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE)
2872 FIELD_::_interlacingType=SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
2875 //A.G. Addings for RC
2877 _support->addReference();
2878 // OCC 10/03/2006 -- According to the rules defined with help of
2879 // MEDMEM_IntrelacingTraits class, it is not allowed to instantiate
2880 // MEDMEM_Array<> template using INTERLACING_TAG parameter of
2881 // FIELD template - MSVC++ 2003 compiler generated an error here.
2882 // _value = (MEDMEM_Array<T, INTERLACING_TAG> *) NULL;
2885 _iterationNumber = iterationNumber;
2887 _orderNumber = orderNumber;
2889 current = addDriver(driverType,fileName,fieldDriverName,MED_EN::RDONLY);
2891 _drivers[current]->open();
2892 _drivers[current]->read();
2893 _drivers[current]->close();
2899 If the mesh argument is not initialized or passed NULL,
2900 this constructor, at least, allows to create a FIELD without creating any
2901 SUPPORT then without having to load a MESH object, a support is created. It
2902 provides the meshName related mesh but doesn't not set a mesh in the created
2904 If the passed mesh contains corresponding support, this support will be used
2905 for the field. This support will be found in mesh by name of one of profiles,
2906 on which the FIELD lays in MED-file. This has sense for the case, then MED-file
2907 was created by MEDMEM, and so name of profile contains name of corresponding support.
2909 template <class T, class INTERLACING_TAG>
2910 FIELD<T,INTERLACING_TAG>::FIELD(driverTypes driverType,
2911 const string & fileName,
2912 const string & fieldDriverName,
2913 const int iterationNumber,
2914 const int orderNumber,
2916 throw (MEDEXCEPTION) :FIELD_()
2919 const char* LOC = "FIELD<T,INTERLACING_TAG>::FIELD( driverTypes driverType, const string & fileName, string & fieldDriverName, int iterationNumber, int orderNumber) : ";
2926 _mesh->addReference();
2928 //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_
2929 ASSERT_MED(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE)
2930 FIELD_::_valueType = SET_VALUE_TYPE<T>::_valueType;
2932 //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_
2933 ASSERT_MED(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE)
2934 FIELD_::_interlacingType = SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType;
2936 _support = (SUPPORT *) NULL;
2937 // OCC 10/03/2006 -- According to the rules defined with help of
2938 // MEDMEM_IntrelacingTraits class, it is not allowed to instantiate
2939 // MEDMEM_Array<> template using INTERLACING_TAG parameter of
2940 // FIELD template - MSVC++ 2003 compiler generated an error here.
2941 // _value = (MEDMEM_Array<T, INTERLACING_TAG> *) NULL;
2944 _iterationNumber = iterationNumber;
2946 _orderNumber = orderNumber;
2948 current = addDriver(driverType,fileName,fieldDriverName,MED_EN::RDONLY);
2950 _drivers[current]->open();
2951 _drivers[current]->read();
2952 _drivers[current]->close();
2963 template <class T, class INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::~FIELD()
2965 const char* LOC = " Destructeur FIELD<T, INTERLACING_TAG>::~FIELD()";
2968 if (_value) delete _value; _value=0;
2969 locMap::const_iterator it;
2970 for ( it = _gaussModel.begin();it != _gaussModel.end(); it++ )
2971 delete (*it).second;
2972 _gaussModel.clear();
2974 _mesh->removeReference();
2982 template <class T, class INTERLACING_TAG>
2983 void FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents)
2985 const char* LOC = "FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents)";
2988 _numberOfComponents = NumberOfComponents ;
2989 _componentsTypes.resize(NumberOfComponents);
2990 _componentsNames.resize(NumberOfComponents);
2991 _componentsDescriptions.resize(NumberOfComponents);
2992 _componentsUnits.resize(NumberOfComponents);
2993 _MEDComponentsUnits.resize(NumberOfComponents);
2994 for (int i=0;i<NumberOfComponents;i++) {
2995 _componentsTypes[i] = 0 ;
2999 // becarefull about the number of gauss point
3000 _numberOfValues = _support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
3001 MESSAGE_MED(PREFIX_MED <<" : "<<_numberOfValues <<" et "<< NumberOfComponents);
3003 //EF : A modifier lors de l'intégration de la classe de localisation des points de gauss
3004 _value = new ArrayNoGauss(_numberOfComponents,_numberOfValues);
3008 catch (MEDEXCEPTION &ex) {
3009 MESSAGE_MED("No value defined, problem with NumberOfComponents (and may be _support) size of MEDARRAY<T>::_value !");
3010 // OCC 10/03/2006 -- According to the rules defined with help of
3011 // MEDMEM_IntrelacingTraits class, it is not allowed to instantiate
3012 // MEDMEM_Array<> template using INTERLACING_TAG parameter of
3013 // FIELD template - MSVC++ 2003 compiler generated an error here.
3014 // _value = (MEDMEM_Array<T, INTERLACING_TAG> *) NULL;
3025 template <class T, class INTERLACING_TAG>
3026 void FIELD<T, INTERLACING_TAG>::allocValue(const int NumberOfComponents,
3027 const int LengthValue)
3029 const char* LOC = "void FIELD<T>::allocValue(const int NumberOfComponents,const int LengthValue)";
3032 _numberOfComponents = NumberOfComponents ;
3033 _componentsTypes.resize(NumberOfComponents);
3034 _componentsNames.resize(NumberOfComponents);
3035 _componentsDescriptions.resize(NumberOfComponents);
3036 _componentsUnits.resize(NumberOfComponents);
3037 _MEDComponentsUnits.resize(NumberOfComponents);
3038 for (int i=0;i<NumberOfComponents;i++) {
3039 _componentsTypes[i] = 0 ;
3042 MESSAGE_MED("FIELD : constructeur : "<<LengthValue <<" et "<< NumberOfComponents);
3043 _numberOfValues = LengthValue ;
3045 //EF : A modifier lors de l'intégration de la classe de localisation des points de gauss
3046 _value = new ArrayNoGauss(_numberOfComponents,_numberOfValues);
3057 template <class T, class INTERLACING_TAG>
3058 void FIELD<T, INTERLACING_TAG>::deallocValue()
3060 const char* LOC = "void FIELD<T, INTERLACING_TAG>::deallocValue()";
3062 _numberOfValues = 0 ;
3063 _numberOfComponents = 0 ;
3064 if (_value != NULL) {
3076 \addtogroup FIELD_io
3079 // -----------------
3081 // -----------------
3084 Creates the specified driver and return its index reference to path to
3085 read or write methods.
3087 \param driverType specifies the file type (MED_DRIVER or VTK_DRIVER)
3088 \param fileName name of the output file
3089 \param driverName name of the field
3090 \param access access type (read, write or both)
3094 template <class T, class INTERLACING_TAG>
3095 int FIELD<T, INTERLACING_TAG>::addDriver(driverTypes driverType,
3096 const string & fileName/*="Default File Name.med"*/,
3097 const string & driverName/*="Default Field Name"*/,
3098 MED_EN::med_mode_acces access)
3100 //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) : ";
3104 const char* LOC = "FIELD<T>::addDriver(driverTypes driverType, const string & fileName,const string & driverName,MED_EN::med_mode_acces access) :";
3107 SCRUTE_MED(driverType);
3109 driver = DRIVERFACTORY::buildDriverForField(driverType,fileName,this,access);
3111 _drivers.push_back(driver);
3113 int current = _drivers.size()-1;
3115 _drivers[current]->setFieldName(driverName);
3123 Read FIELD in the file specified in the driver given by its index.
3125 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::read(int index/*=0*/)
3127 const char * LOC = "FIELD<T, INTERLACING_TAG>::read(int index=0) : ";
3130 if ( index>=0 && index<(int)_drivers.size() && _drivers[index] ) {
3131 _drivers[index]->open();
3134 _drivers[index]->read();
3136 catch ( const MEDEXCEPTION& ex )
3138 _drivers[index]->close();
3141 _drivers[index]->close();
3144 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
3145 << "The index given is invalid, index must be between 0 and |"
3153 Read FIELD with the driver. Additional information (name etc.) to select a field
3154 must be set to the field.
3156 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::read(const GENDRIVER & driver )
3158 const char* LOC = " FIELD<T, INTERLACING_TAG>::read(const GENDRIVER &) : ";
3161 // For the case where driver does not know about me since it has been created through
3162 // constructor witout parameters: create newDriver knowing me and get missing data
3163 // from driver using merge()
3164 std::auto_ptr<GENDRIVER> newDriver( DRIVERFACTORY::buildDriverForField(driver.getDriverType(),
3165 driver.getFileName(),
3167 newDriver->merge( driver );
3174 catch ( const MEDEXCEPTION& ex )
3185 Read FIELD with driver of the given type. Additional information (name etc.) to select a field
3186 must be set to the field.
3188 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::read(driverTypes driverType, const std::string& filename)
3190 const char* LOC = " FIELD<T, INTERLACING_TAG>::read(driverTypes driverType, const std::string& filename) : ";
3193 std::auto_ptr<GENDRIVER> newDriver( DRIVERFACTORY::buildDriverForField(driverType, filename,
3200 catch ( const MEDEXCEPTION& ex )
3210 /*! \if MEDMEM_ug @} \endif */
3213 Duplicates the given driver and return its index reference to path to
3214 read or write methods.
3216 template <class T, class INTERLACING_TAG>
3217 inline int FIELD<T, INTERLACING_TAG>::addDriver (GENDRIVER & driver )
3221 const char* LOC = "FIELD<T, INTERLACING_TAG>::addDriver(GENDRIVER &) : ";
3224 GENDRIVER * newDriver =
3225 DRIVERFACTORY::buildDriverForField(driver.getDriverType(),
3226 driver.getFileName(), this,
3227 driver.getAccessMode());
3228 _drivers.push_back(newDriver);
3230 current = _drivers.size()-1;
3231 SCRUTE_MED(current);
3232 driver.setId(current);
3234 newDriver->merge( driver );
3235 newDriver->setId(current);
3241 Remove the driver referenced by its index.
3243 template <class T, class INTERLACING_TAG>
3244 void FIELD<T, INTERLACING_TAG>::rmDriver (int index/*=0*/)
3246 const char * LOC = "FIELD<T, INTERLACING_TAG>::rmDriver (int index=0): ";
3249 if ( index>=0 && index<(int)_drivers.size() && _drivers[index] ) {
3250 MESSAGE_MED ("detruire");
3253 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
3254 << "The <index given is invalid, index must be between 0 and |"
3263 \addtogroup FIELD_io
3268 Writes FIELD in the file specified by the driver handle \a index.
3273 // Attaching the friver to file "output.med", meshname "Mesh"
3274 int driver_handle = mesh.addDriver(MED_DRIVER, "output.med", "Mesh");
3275 // Writing the content of mesh to the file
3276 mesh.write(driver_handle);
3279 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::write(int index/*=0*/)
3281 const char * LOC = "FIELD<T,INTERLACING_TAG>::write(int index=0, const string & driverName = \"\") : ";
3284 if( index>=0 && index<(int)_drivers.size() && _drivers[index] ) {
3285 _drivers[index]->open();
3288 _drivers[index]->write();
3290 catch ( const MEDEXCEPTION& ex )
3292 _drivers[index]->close();
3295 _drivers[index]->close();
3298 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
3299 << "The index given is invalid, index must be between 0 and |"
3306 Write FIELD with the given driver.
3308 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::write(const GENDRIVER & driver, MED_EN::med_mode_acces medMode/*=MED_EN::RDWR*/)
3310 const char* LOC = " FIELD<T, INTERLACING_TAG>::write(const GENDRIVER &) : ";
3313 // For the case where driver does not know about me since it has been created through
3314 // constructor witout parameters: create newDriver knowing me and get missing data
3315 // from driver using merge()
3316 std::auto_ptr<GENDRIVER> newDriver( DRIVERFACTORY::buildDriverForField(driver.getDriverType(),
3317 driver.getFileName(),
3319 newDriver->merge( driver );
3320 if ( newDriver->getDriverType() == MED_DRIVER )
3321 newDriver->setAccessMode( MED_EN::med_mode_acces( getMedAccessMode( medMode ) ));
3328 catch ( const MEDEXCEPTION& ex )
3339 Write FIELD with driver of the given type.
3341 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::write(driverTypes driverType, const std::string& filename, MED_EN::med_mode_acces medMode/*=MED_EN::RDWR*/)
3343 const char* LOC = " FIELD<T, INTERLACING_TAG>::write(driverTypes driverType, const std::string& filename) : ";
3346 std::auto_ptr<GENDRIVER> newDriver( DRIVERFACTORY::buildDriverForField(driverType, filename,
3348 if ( newDriver->getDriverType() == MED_DRIVER )
3349 newDriver->setAccessMode( MED_EN::med_mode_acces( getMedAccessMode( medMode ) ));
3356 catch ( const MEDEXCEPTION& ex )
3366 /*! \if MEDMEM_ug @} \endif */
3368 Write FIELD in the file specified in the driver given by its index. Use this
3369 method for ASCII drivers (e.g. VTK_DRIVER)
3371 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::writeAppend(int index/*=0*/, const string & driverName /*= ""*/)
3373 const char * LOC = "FIELD<T,INTERLACING_TAG>::write(int index=0, const string & driverName = \"\") : ";
3376 if( index>=0 && index<(int)_drivers.size() && _drivers[index] ) {
3377 _drivers[index]->openAppend();
3378 if (driverName != "") _drivers[index]->setFieldName(driverName);
3381 _drivers[index]->writeAppend();
3383 catch ( const MEDEXCEPTION& ex )
3385 _drivers[index]->close();
3388 _drivers[index]->close();
3391 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
3392 << "The index given is invalid, index must be between 0 and |"
3401 Write FIELD with the driver which is equal to the given driver.
3403 Use by MED object. Use this method for ASCII drivers (e.g. VTK_DRIVER).
3405 template <class T, class INTERLACING_TAG> inline void FIELD<T, INTERLACING_TAG>::writeAppend(const GENDRIVER & genDriver)
3407 const char* LOC = " FIELD<T, INTERLACING_TAG>::write(const GENDRIVER &) : ";
3410 for (unsigned int index=0; index < _drivers.size(); index++ )
3411 if ( *_drivers[index] == genDriver ) {
3412 _drivers[index]->openAppend();
3415 _drivers[index]->writeAppend();
3417 catch ( const MEDEXCEPTION& ex )
3419 _drivers[index]->close();
3422 _drivers[index]->close();
3430 Fills in already allocated retValues array the values related to eltIdInSup.
3431 If the element does not exist in this->_support false is returned, true otherwise.
3433 template <class T, class INTERLACING_TAG>
3434 bool FIELD<T, INTERLACING_TAG>::getValueOnElement(int eltIdInSup,T* retValues)
3435 const throw (MEDEXCEPTION)
3440 if(_support->isOnAllElements())
3442 int nbOfEltsThis=_support->getMesh()->getNumberOfElements(_support->getEntity(),MED_EN::MED_ALL_ELEMENTS);
3443 if(eltIdInSup>nbOfEltsThis)
3445 const T* valsThis=getValue();
3446 for(int j=0;j<_numberOfComponents;j++)
3447 retValues[j]=valsThis[(eltIdInSup-1)*_numberOfComponents+j];
3452 int nbOfEltsThis=_support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
3453 const int *eltsThis=_support->getNumber(MED_EN::MED_ALL_ELEMENTS);
3456 for(iThis=0;iThis<nbOfEltsThis && !found;)
3457 if(eltsThis[iThis]==eltIdInSup)
3463 const T* valsThis=getValue();
3464 for(int j=0;j<_numberOfComponents;j++)
3465 retValues[j]=valsThis[iThis*_numberOfComponents+j];
3471 * \brief Retrieve value in a given point
3472 * \param coords - point coordinates
3473 * \param output - output buffer
3475 template <class T, class INTERLACING_TAG>
3476 void FIELD<T, INTERLACING_TAG>::getValueOnPoint(const double* coords, double* output) const throw (MEDEXCEPTION)
3478 getValueOnPoints(1, coords, output);
3482 * \brief Retrieve values in given points
3483 * \param nb_points - number of points
3484 * \param coords - point coordinates
3485 * \param output - output buffer
3487 template <class T, class INTERLACING_TAG>
3488 void FIELD<T, INTERLACING_TAG>::getValueOnPoints(int nb_points, const double* coords, double* output) const throw (MEDEXCEPTION)
3490 const char* LOC = " FIELD<T, INTERLACING_TAG>::getValueOnPoints(int nb_points, const double* coords, double* output) : ";
3491 // check operation feasibility
3492 if ( !getSupport() ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"NULL Support"));
3493 if ( !getSupport()->getMesh() ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"NULL Mesh"));
3494 if ( !_value ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"NULL _value"));
3495 if ( getGaussPresence() ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not implemeneted for Gauss points"));
3497 MED_EN::medEntityMesh entity = getSupport()->getEntity();
3498 if ( entity != MED_EN::MED_CELL &&
3499 entity != MED_EN::MED_NODE )
3500 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support must be on CELLs or NODEs"));
3502 // initialize output value
3503 for ( int j = 0; j < nb_points*getNumberOfComponents(); ++j )
3506 const MEDMEM::MESH* mesh = getSupport()->getMesh()->convertInMESH();
3507 MEDMEM::AutoDeref derefMesh( mesh );
3509 const double* point = coords;
3510 double* value = output;
3512 if ( entity == MED_EN::MED_CELL )
3514 MEDMEM::PointLocator pLocator (*mesh);
3515 for ( int i = 0; i < nb_points; ++i)
3517 // find the cell enclosing the point
3518 std::list<int> cellIds = pLocator.locate( point );
3519 int nbCells = cellIds.size();
3521 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Point is out of mesh"));
3524 std::list<int>::iterator iCell = cellIds.begin();
3525 for ( ; iCell != cellIds.end(); ++iCell )
3526 for ( int j = 1; j <= getNumberOfComponents(); ++j )
3527 value[j-1] += getValueIJ( *iCell, j ) / nbCells;
3530 point += mesh->getSpaceDimension();
3531 value += getNumberOfComponents();
3534 else // MED_EN::MED_NODE
3536 const double * allCoords = mesh->getCoordinates( MED_EN::MED_FULL_INTERLACE );
3538 MEDMEM::PointLocatorInSimplex pLocator (*mesh);
3539 for ( int i = 0; i < nb_points; ++i)
3541 // find nodes of the simplex enclosing the point
3542 std::list<int> nodeIds = pLocator.locate( point );
3543 int nbNodes = nodeIds.size();
3545 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Point is out of mesh"));
3546 if ( nbNodes != mesh->getMeshDimension() + 1 )
3547 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Invalid nb of points of simplex: "<<nbNodes));
3549 // get coordinates of simplex nodes
3550 std::vector<const double*> nodeCoords( nbNodes );
3551 std::list<int>::iterator iNode = nodeIds.begin();
3553 for ( ; n < nbNodes; ++iNode, ++n )
3554 nodeCoords[n] = allCoords + (*iNode-1) * mesh->getSpaceDimension();
3556 // compute wegths of simplex nodes
3558 pLocator.getNodeWightsInSimplex( nodeCoords, coords, nodeWgt );
3561 for ( n = 0, iNode = nodeIds.begin(); iNode != nodeIds.end(); ++iNode, ++n )
3562 for ( int j = 1; j <= getNumberOfComponents(); ++j )
3563 value[j-1] += getValueIJ( *iNode, j ) * nodeWgt[ n ];
3566 point += mesh->getSpaceDimension();
3567 value += getNumberOfComponents();
3574 Return the coordinates of the gauss points
3575 The returned field has SPACEDIM components
3577 template <class T, class INTERLACING_TAG>
3578 FIELD<double, FullInterlace>* FIELD<T, INTERLACING_TAG>::getGaussPointsCoordinates() const
3579 throw (MEDEXCEPTION)
3581 const char * LOC = "FIELD::getGaussPointsCoordinates() : ";
3585 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
3587 const MEDMEM::MESH* mesh = getSupport()->getMesh()->convertInMESH();
3588 MEDMEM::AutoDeref derefMesh( mesh );
3590 const double * coord = mesh->getCoordinates(MED_FULL_INTERLACE);
3591 int spaceDim = mesh->getSpaceDimension();
3593 //Init calculator of the gauss point coordinates
3594 INTERP_KERNEL::GaussCoords calculator;
3595 locMap::const_iterator it;
3597 int nb_type = getSupport()->getNumberOfTypes();
3598 int length_values = getSupport()->getNumberOfElements(MED_ALL_ELEMENTS);
3599 const medGeometryElement* types = getSupport()->getTypes();
3600 medEntityMesh support_entity = getSupport()->getEntity();
3601 bool isOnAll = getSupport()->isOnAllElements();
3603 const int* global_connectivity = 0;
3604 const GAUSS_LOCALIZATION<INTERLACING_TAG>* gaussLock = NULL;
3606 typedef typename MEDMEM_ArrayInterface<double,INTERLACING_TAG,NoGauss>::Array ArrayCoord;
3607 typedef typename MEDMEM_ArrayInterface<double,INTERLACING_TAG,Gauss>::Array TArrayGauss;
3609 vector<int> nbelgeoc, nbgaussgeo;
3611 nbelgeoc.resize(nb_type+1, 0);
3612 nbgaussgeo.resize(nb_type+1, 0);
3614 for ( int iType = 0 ; iType < nb_type ; iType++ ) {
3616 medGeometryElement elem_type = types[iType] ;
3617 if(elem_type == MED_EN::MED_POLYGON && elem_type == MED_EN::MED_POLYHEDRA )
3618 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Bad cell type : "<<MED_EN::geoNames[elem_type]<<" !!! "));
3620 it = _gaussModel.find(elem_type);
3622 if(it == _gaussModel.end())
3623 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Gauss localization not defined for "<<MED_EN::geoNames[elem_type]<<" type!!! "));
3624 gaussLock = static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ((*it).second);
3626 ArrayCoord coord = gaussLock->getGsCoo();
3627 double* gaussCoord = new double[coord.getNbElem()*coord.getDim()];
3629 for( int i = 1 ; i <= coord.getNbElem() ; i++ ) {
3630 for( int j = 1 ; j <= coord.getDim() ; j++ ) {
3631 gaussCoord[idx++] = coord.getIJ(i,j);
3636 ArrayCoord ref = gaussLock->getRefCoo();
3637 double* refCoord = new double[ref.getNbElem()*ref.getDim()];
3638 for( int i = 1 ; i <= ref.getNbElem() ; i++ ) {
3639 for( int j = 1 ; j <= ref.getDim() ; j++ ) {
3640 refCoord[idx++] = ref.getIJ(i,j);
3644 INTERP_KERNEL::NormalizedCellType normType;
3646 case MED_EN::MED_SEG2 : normType = INTERP_KERNEL::NORM_SEG2;break;
3647 case MED_EN::MED_SEG3 : normType = INTERP_KERNEL::NORM_SEG3;break;
3648 default : normType = (INTERP_KERNEL::NormalizedCellType) ((((unsigned long)elem_type/100-2)*10) + ((unsigned long)elem_type%100));
3652 calculator.addGaussInfo(normType,
3655 gaussLock->getNbGauss(),
3659 // Preapre Info for the gauss array
3660 nbelgeoc [ iType+1 ] = nbelgeoc[ iType ] + getSupport()->getNumberOfElements(elem_type);
3661 nbgaussgeo [ iType+1 ] = gaussLock->getNbGauss();
3663 delete [] gaussCoord;
3667 FIELD<double, FullInterlace>* gpCoord =
3668 new FIELD<double, FullInterlace>(getSupport(),spaceDim);
3669 gpCoord->setName("Gauss Points Coordinates");
3670 gpCoord->setDescription("Gauss Points Coordinates");
3672 for(int dimId = 1 ; dimId <= spaceDim; dimId++) {
3675 gpCoord->setComponentName(dimId,"X");
3676 gpCoord->setComponentDescription(dimId,"X coordinate of the gauss point");
3679 gpCoord->setComponentName(dimId,"Y");
3680 gpCoord->setComponentDescription(dimId,"Y coordinate of the gauss point");
3683 gpCoord->setComponentName(dimId,"Z");
3684 gpCoord->setComponentDescription(dimId,"Z coordinate of the gauss point");
3688 gpCoord->setMEDComponentUnit(dimId, mesh->getCoordinatesUnits()[dimId-1]);
3691 gpCoord->setIterationNumber(getIterationNumber());
3692 gpCoord->setOrderNumber(getOrderNumber());
3693 gpCoord->setTime(getTime());
3695 TArrayGauss *arrayGauss = new TArrayGauss(spaceDim, length_values,
3696 nb_type, & nbelgeoc[0], & nbgaussgeo[0]);
3697 gpCoord->setArray(arrayGauss);
3702 //Calculation of the coordinates
3704 for ( int i = 0 ; i < nb_type ; i++ ) {
3706 medGeometryElement type = types[i] ;
3707 INTERP_KERNEL::NormalizedCellType normType;
3709 case MED_EN::MED_SEG2 : normType = INTERP_KERNEL::NORM_SEG2;break;
3710 case MED_EN::MED_SEG3 : normType = INTERP_KERNEL::NORM_SEG3;break;
3711 default : normType = (INTERP_KERNEL::NormalizedCellType) ((((unsigned long)type/100-2)*10) + ((unsigned long)type%100));
3715 it = _gaussModel.find(type);
3717 gaussLock = static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ((*it).second);
3718 int nb_entity_type = getSupport()->getNumberOfElements(type);
3722 global_connectivity = mesh->getConnectivity(MED_NODAL,support_entity,type);
3725 const int * supp_number = getSupport()->getNumber(type);
3726 const int * connectivity = mesh->getConnectivity(MED_NODAL,support_entity,MED_ALL_ELEMENTS);
3727 const int * connectivityIndex = mesh->getConnectivityIndex(MED_NODAL,support_entity);
3728 int * global_connectivity_tmp = new int[(type%100)*nb_entity_type];
3730 for (int k_type = 0; k_type<nb_entity_type; k_type++) {
3731 for (int j_ent = 0; j_ent<(type%100); j_ent++) {
3732 global_connectivity_tmp[k_type*(type%100)+j_ent] = connectivity[connectivityIndex[supp_number[k_type]-1]+j_ent-1];
3735 global_connectivity = global_connectivity_tmp;
3738 int nbNodes = (type%100);
3739 double* gCoord = NULL;
3742 for ( int elem = 0; elem < nb_entity_type; elem++ ) {
3743 int elem_index = nbNodes*elem;
3744 Ni = new int[nbNodes];
3745 for( int idx = 0 ; idx < nbNodes; idx++ ) {
3746 Ni[idx] = global_connectivity[ elem_index+idx ] - 1;
3749 gCoord = calculator.calculateCoords(normType,
3753 int resultIndex = 0;
3754 for( int k = 0; k < gaussLock->getNbGauss(); k++ ) {
3755 for( int dimId = 1; dimId <= spaceDim; dimId++ ) {
3756 gpCoord->setValueIJK(index,dimId,(k+1),gCoord[resultIndex]);
3764 if (!isOnAll && type != MED_EN::MED_POLYHEDRA && type != MED_EN::MED_POLYGON) {
3765 delete [] global_connectivity ;
3774 Destroy the MEDARRAY<T> in FIELD and put the new one without copy.
3777 template <class T, class INTERLACING_TAG>
3778 inline void FIELD<T, INTERLACING_TAG>::setArray(MEDMEM_Array_ * Value)
3779 throw (MEDEXCEPTION)
3781 if (NULL != _value) delete _value ;
3787 Return a reference to the MEDARRAY<T, INTERLACING_TAG> in FIELD.
3790 template <class T, class INTERLACING_TAG>
3791 inline MEDMEM_Array_ * FIELD<T, INTERLACING_TAG>::getArray() const throw (MEDEXCEPTION)
3793 const char* LOC = "MEDMEM_Array_ * FIELD<T, INTERLACING_TAG>::getArray() : ";
3798 template <class T,class INTERLACING_TAG> inline
3799 typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,Gauss>::Array *
3800 FIELD<T, INTERLACING_TAG>::getArrayGauss() const throw (MEDEXCEPTION)
3802 const char * LOC = "FIELD<T, INTERLACING_TAG>::getArrayGauss() : ";
3805 if ( getGaussPresence() )
3806 return static_cast<ArrayGauss *> (_value);
3808 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<
3809 "The field has no Gauss Point"));
3815 template <class T,class INTERLACING_TAG> inline
3816 typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,NoGauss>::Array *
3817 FIELD<T, INTERLACING_TAG>::getArrayNoGauss() const throw (MEDEXCEPTION)
3819 const char * LOC = "FIELD<T, INTERLACING_TAG>::getArrayNoGauss() : ";
3822 if ( ! getGaussPresence() )
3823 return static_cast < ArrayNoGauss * > (_value);
3825 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<
3826 "The field has Gauss Point"));
3832 template <class T,class INTERLACING_TAG> inline bool
3833 FIELD<T, INTERLACING_TAG>::getGaussPresence() const throw (MEDEXCEPTION)
3836 return _value->getGaussPresence();
3838 throw MEDEXCEPTION("FIELD<T, INTERLACING_TAG>::getGaussPresence() const : Can't call getGaussPresence on a null _value");
3842 Return the actual length of the reference to values array returned by getValue.
3843 Take care of number of components and number of Gauss points by geometric type
3845 template <class T, class INTERLACING_TAG>
3846 inline int FIELD<T, INTERLACING_TAG>::getValueLength() const
3847 throw (MEDEXCEPTION)
3849 if ( getGaussPresence() )
3850 return static_cast<ArrayGauss *>(_value)->getArraySize() ;
3852 return static_cast<ArrayNoGauss *>(_value)->getArraySize() ;
3857 \defgroup FIELD_value Field values
3859 These methods are provided for accessing the values of a field.
3860 There are two ways to do so : one consists in using accessors
3861 that retrieve elements or group of elements from the entire field. Typical use is
3863 FIELD field(MED_DRIVER, "result.med","Pressure");
3864 double P0=field.getValueIJ(1,1);
3867 Another way is to retrieve the pointer to the array that contains the
3868 variable values. In this case, the user should be aware of the interlacing mode
3869 so that no mistakes are made when retrieving the values.
3872 FIELD field(MED_DRIVER, "result.med","Pressure");
3873 double* ptrP=field.getValue();
3881 Returns a reference to values array to read them.
3883 template <class T, class INTERLACIN_TAG>
3884 inline const T* FIELD<T, INTERLACIN_TAG>::getValue() const throw (MEDEXCEPTION)
3886 const char* LOC = "FIELD<T, INTERLACING_TAG>::getValue() : ";
3888 if ( getGaussPresence() )
3889 return static_cast<ArrayGauss *>(_value)->getPtr() ;
3891 return static_cast<ArrayNoGauss *>(_value)->getPtr() ;
3894 Returns a reference to \f$ i^{th} \f$ row
3895 of FIELD values array.
3896 If a faster accessor is intended you may use getArray() once,
3897 then MEDMEM_Array accessors.
3898 Be careful if field support is not on all elements getRow
3899 use support->getValIndFromGlobalNumber(i).
3901 template <class T,class INTERLACING_TAG> inline
3903 FIELD<T,INTERLACING_TAG>::getRow(int i) const throw (MEDEXCEPTION)
3905 const char* LOC; LOC = "FIELD<T,INTERLACING_TAG>::getRow(int i) : ";
3909 valIndex = _support->getValIndFromGlobalNumber(i);
3911 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
3913 if ( getGaussPresence() )
3914 return static_cast<ArrayGauss *>(_value)->getRow(valIndex) ;
3916 return static_cast<ArrayNoGauss *>(_value)->getRow(valIndex) ;
3920 Returns a reference to $j^{th}$ column
3921 of FIELD values array.
3923 template <class T,class INTERLACING_TAG> inline const T*
3924 FIELD<T,INTERLACING_TAG>::getColumn(int j) const throw (MEDEXCEPTION)
3926 if ( getGaussPresence() )
3927 return static_cast<ArrayGauss *>(_value)->getColumn(j) ;
3929 return static_cast<ArrayNoGauss *>(_value)->getColumn(j) ;
3933 Returns the value of $i^{th}$ element and $j^{th}$ component.
3934 This method only works with fields having no particular Gauss point
3935 definition (i.e., fields having one value per element).
3936 This method makes the retrieval of the value independent from the
3937 interlacing pattern, but it is slower than the complete retrieval
3938 obtained by the \b getValue() method.
3940 template <class T,class INTERLACING_TAG> inline T FIELD<T,INTERLACING_TAG>::getValueIJ(int i,int j) const throw (MEDEXCEPTION)
3942 const char * LOC = "getValueIJ(..)";
3945 valIndex = _support->getValIndFromGlobalNumber(i);
3947 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
3949 if ( getGaussPresence() )
3950 return static_cast<ArrayGauss *>(_value)->getIJ(valIndex,j) ;
3952 return static_cast<ArrayNoGauss *>(_value)->getIJ(valIndex,j) ;
3956 Returns the $j^{th}$ component of $k^{th}$ Gauss points of $i^{th}$ value.
3957 This method is compatible with elements having more than one Gauss point.
3958 This method makes the retrieval of the value independent from the
3959 interlacing pattern, but it is slower than the complete retrieval
3960 obtained by the \b getValue() method.
3962 template <class T,class INTERLACING_TAG> inline T FIELD<T,INTERLACING_TAG>::getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION)
3964 const char * LOC = "getValueIJK(..)";
3967 valIndex = _support->getValIndFromGlobalNumber(i);
3969 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
3971 if ( getGaussPresence() )
3972 return static_cast<ArrayGauss *>(_value)->getIJK(valIndex,j,k) ;
3974 return static_cast<ArrayNoGauss *>(_value)->getIJK(valIndex,j,k) ;
3976 /*! \if MEDMEM_ug @} \endif */
3979 Return number of values of a geomertic type in NoInterlaceByType mode
3981 template <class T, class INTERLACIN_TAG>
3982 inline int FIELD<T, INTERLACIN_TAG>::getValueByTypeLength(int t) const throw (MEDEXCEPTION)
3984 const char * LOC ="getValueByTypeLength() : ";
3985 if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
3986 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
3988 if ( getGaussPresence() ) {
3989 ArrayNoByTypeGauss* array = static_cast<ArrayNoByTypeGauss *>(_value);
3990 if ( t < 1 || t > array->getNbGeoType() )
3991 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Invalid type: "<< t ));
3992 return array->getLengthOfType( t );
3995 ArrayNoByType* array = static_cast<ArrayNoByType *>(_value);
3996 if ( t < 1 || t > array->getNbGeoType() )
3997 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Invalid type: "<< t ));
3998 return array->getLengthOfType( t );
4003 Return a reference to values array to read them.
4005 template <class T, class INTERLACIN_TAG>
4006 inline const T* FIELD<T, INTERLACIN_TAG>::getValueByType(int t) const throw (MEDEXCEPTION)
4008 if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
4009 throw MEDEXCEPTION(LOCALIZED("getValueByType() : not MED_NO_INTERLACE_BY_TYPE field" ));
4011 if ( getGaussPresence() ) {
4012 ArrayNoByTypeGauss* array = static_cast<ArrayNoByTypeGauss *>(_value);
4013 return array->getPtr() + array->getIndex( t );
4016 ArrayNoByType* array = static_cast<ArrayNoByType *>(_value);
4017 return array->getPtr() + array->getIndex( t );
4022 Return the value of i^{th} element in indicated type t and j^{th} component.
4024 template <class T,class INTERLACING_TAG> inline T FIELD<T,INTERLACING_TAG>::getValueIJByType(int i,int j, int t) const throw (MEDEXCEPTION)
4026 const char * LOC = "getValueIJByType(..)";
4027 if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
4028 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
4030 if ( getGaussPresence() )
4031 return static_cast<ArrayNoByTypeGauss *>(_value)->getIJByType(i,j,t) ;
4033 return static_cast<ArrayNoByType *>(_value)->getIJByType(i,j,t) ;
4037 Return the j^{th} component of k^{th} gauss points of i^{th} value with type t.
4039 template <class T,class INTERLACING_TAG> inline T FIELD<T,INTERLACING_TAG>::getValueIJKByType(int i,int j,int k,int t) const throw (MEDEXCEPTION)
4041 const char * LOC = "getValueIJKByType(..)";
4042 if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
4043 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
4045 if ( getGaussPresence() )
4046 return static_cast<ArrayNoByTypeGauss *>(_value)->getIJKByType(i,j,k,t) ;
4048 return static_cast<ArrayNoByType *>(_value)->getIJKByType(i,j,k,t) ;
4052 template <class T,class INTERLACING_TAG> const int FIELD<T,INTERLACING_TAG>::getNumberOfGeometricTypes() const throw (MEDEXCEPTION)
4054 const char * LOC = "getNumberOfGeometricTypes(..)";
4057 return _support->getNumberOfTypes();
4059 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
4064 \addtogroup FIELD_gauss
4069 template <class T,class INTERLACING_TAG> const GAUSS_LOCALIZATION<INTERLACING_TAG> &
4070 FIELD<T,INTERLACING_TAG>::getGaussLocalization(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION)
4072 const char * LOC ="getGaussLocalization(MED_EN::medGeometryElement geomElement) : ";
4073 const GAUSS_LOCALIZATION_ * locPtr=0;
4075 locMap::const_iterator it;
4076 if ( ( it = _gaussModel.find(geomElement)) != _gaussModel.end() ) {
4077 locPtr = (*it).second;
4078 return *static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> *>(locPtr);
4081 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't find any GaussLocalization on this geometric type" ));
4085 template <class T,class INTERLACING_TAG> const GAUSS_LOCALIZATION<INTERLACING_TAG> *
4086 FIELD<T,INTERLACING_TAG>::getGaussLocalizationPtr(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION)
4088 const char * LOC ="getGaussLocalizationPtr(MED_EN::medGeometryElement geomElement) : ";
4089 const GAUSS_LOCALIZATION_ * locPtr=0;
4091 locMap::const_iterator it;
4092 if ( ( it = _gaussModel.find(geomElement)) != _gaussModel.end() ) {
4093 locPtr = (*it).second;
4094 return static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> *>(locPtr);
4097 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't find any GaussLocalization on this geometric type" ));
4102 * \brief Return GAUSS_LOCALIZATION_* whose interlacing type may differ from one of the field
4104 template <class T,class INTERLACING_TAG> const GAUSS_LOCALIZATION_ *
4105 FIELD<T,INTERLACING_TAG>::getGaussLocalizationRoot(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION)
4107 const char * LOC ="getGaussLocalizationRoot(MED_EN::medGeometryElement geomElement) : ";
4109 locMap::const_iterator it;
4110 if ( ( it = _gaussModel.find(geomElement)) != _gaussModel.end() ) {
4111 return (*it).second;
4114 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't find any GaussLocalization on this geometric type: "<< geomElement ));
4119 * \brief Take onership of GAUSS_LOCALIZATION_* whose interlacing type may differ from one of the field
4121 template <class T,class INTERLACING_TAG> void
4122 FIELD<T,INTERLACING_TAG>::setGaussLocalization(MED_EN::medGeometryElement geomElement, GAUSS_LOCALIZATION_* gaussloc)
4124 locMap::iterator it = _gaussModel.find(geomElement);
4125 if ( it != _gaussModel.end() ) {
4127 it->second = gaussloc;
4130 _gaussModel[ geomElement ] = gaussloc;
4135 template <class T,class INTERLACING_TAG> void
4136 FIELD<T,INTERLACING_TAG>::setGaussLocalization(MED_EN::medGeometryElement geomElement, const GAUSS_LOCALIZATION<INTERLACING_TAG>& gaussloc)
4138 locMap::iterator it = _gaussModel.find(geomElement);
4139 if ( it != _gaussModel.end() ) {
4141 it->second = new GAUSS_LOCALIZATION<INTERLACING_TAG> (gaussloc);
4144 _gaussModel[ geomElement ] = new GAUSS_LOCALIZATION<INTERLACING_TAG> (gaussloc);
4149 Returns number of Gauss points for this medGeometryElement.
4152 if there is no GAUSS_LOCALIZATION having this medGeometryElement but
4153 the medGeometryElement exist in the SUPPORT, getNumberOfGaussPoints
4156 template <class T,class INTERLACING_TAG> const int FIELD<T,INTERLACING_TAG>::getNumberOfGaussPoints(MED_EN::medGeometryElement geomElement) const
4157 throw (MEDEXCEPTION)
4159 const char * LOC ="getNumberOfGaussPoints(MED_EN::medGeometryElement geomElement) : ";
4160 const GAUSS_LOCALIZATION_ * locPtr=0;
4162 locMap::const_iterator it;
4163 if ( ( it = _gaussModel.find(geomElement)) != _gaussModel.end() ) {
4164 locPtr = (*it).second;
4165 return static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> *>(locPtr)->getNbGauss();
4170 if ( _support->getNumberOfElements(geomElement) ) return 1;
4171 } catch ( MEDEXCEPTION & ex) {
4172 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "GeometricType not found !" )) ;
4175 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
4177 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Should never execute this!" ));
4182 Returns number of Gauss points for each geometric type.
4185 if there is no gauss points whatever the geometric type is
4186 it returns an exception. (renvoyer un tableau de 1 ?)
4188 template <class T,class INTERLACING_TAG> const int * FIELD<T,INTERLACING_TAG>::getNumberOfGaussPoints() const
4189 throw (MEDEXCEPTION)
4191 const char * LOC ="const int * getNumberOfGaussPoints(MED_EN::medGeometryElement geomElement) : ";
4194 if ( getGaussPresence() ) {
4195 return static_cast<ArrayGauss *>(_value)->getNbGaussGeo()+1;
4197 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"value hasn't Gauss points " ));
4200 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Value not defined" ));
4204 Returns number of Gauss points for element n°i.
4205 The i index is a global index (take care of previous element
4206 on different geometric type).
4208 template <class T,class INTERLACING_TAG> const int FIELD<T,INTERLACING_TAG>::getNbGaussI(int i) const throw (MEDEXCEPTION)
4210 const char * LOC = "getNbGaussI(..)";
4214 valIndex = _support->getValIndFromGlobalNumber(i);
4216 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
4219 if ( getGaussPresence() )
4220 return static_cast<ArrayGauss *>(_value)->getNbGauss(valIndex) ;
4222 return static_cast<ArrayNoGauss *>(_value)->getNbGauss(valIndex) ;
4224 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"_value not defined" ));
4231 template <class T,class INTERLACING_TAG> const int * FIELD<T,INTERLACING_TAG>::getNumberOfElements() const throw (MEDEXCEPTION)
4233 const char * LOC = "getNumberOfElements(..)";
4236 return _support->getNumberOfElements();
4238 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
4242 template <class T,class INTERLACING_TAG> const MED_EN::medGeometryElement * FIELD<T,INTERLACING_TAG>::getGeometricTypes() const throw (MEDEXCEPTION)
4244 const char * LOC = "getGeometricTypes(..)";
4247 return _support->getTypes();
4249 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
4252 template <class T,class INTERLACING_TAG> bool FIELD<T,INTERLACING_TAG>::isOnAllElements() const throw (MEDEXCEPTION)
4254 const char * LOC = "isOnAllElements(..)";
4257 return _support->isOnAllElements();
4259 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" ));
4265 \addtogroup FIELD_value
4270 Copy new values array in FIELD according to the given mode.
4272 Array must have right size. If not results are unpredicable.
4273 In MED_FULL_INTERLACE mode, values are stored elementwise in X1,Y1,Z1,X2,Y2,Z2.. order.
4274 In MED_NO_INTERLACE mode, values are stored componentwise in X1,X2,X3,...,Y1,Y2,Y3,... order.
4276 template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValue( T* value) throw (MEDEXCEPTION)
4278 if ( getGaussPresence() )
4279 static_cast<ArrayGauss *>(_value)->setPtr(value) ;
4281 static_cast<ArrayNoGauss *>(_value)->setPtr(value) ;
4285 Update values array in the j^{th} row of FIELD values array with the given ones and
4286 according to specified mode.
4288 template <class T,class INTERLACING_TAG>
4289 inline void FIELD<T,INTERLACING_TAG>::setRow( int i, T* value) throw (MEDEXCEPTION)
4291 const char * LOC = "FIELD<T,INTERLACING_TAG>::setRow(int i, T* value) : ";
4294 valIndex = _support->getValIndFromGlobalNumber(i);
4296 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
4298 if ( getGaussPresence() )
4299 static_cast<ArrayGauss *>(_value)->setRow(valIndex, value) ;
4301 static_cast<ArrayNoGauss *>(_value)->setRow(valIndex, value) ;
4305 Update values array in the $j^{th}$ column of FIELD values array with the given ones and
4306 according to specified mode.
4308 template <class T,class INTERLACING_TAG>
4309 inline void FIELD<T,INTERLACING_TAG>::setColumn( int j, T* value) throw (MEDEXCEPTION)
4311 if ( getGaussPresence() )
4312 static_cast<ArrayGauss *>(_value)->setColumn(j, value) ;
4314 static_cast<ArrayNoGauss *>(_value)->setColumn(j, value) ;
4318 Sets the value of i^{th} element and j^{th} component with the given one.
4320 template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValueIJ(int i, int j, T value) throw (MEDEXCEPTION)
4322 const char * LOC = "FIELD<T,INTERLACING_TAG>::setValueIJ(int i, int j, T value) : ";
4325 valIndex = _support->getValIndFromGlobalNumber(i);
4327 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
4329 if ( getGaussPresence() )
4330 static_cast<ArrayGauss *>(_value)->setIJ(valIndex,j,value) ;
4332 static_cast<ArrayNoGauss *>(_value)->setIJ(valIndex,j,value) ;
4336 Set the value of i^{th} element, j^{th} component and k^{th} gauss point with the given one.
4338 template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValueIJK(int i, int j, int k, T value) throw (MEDEXCEPTION)
4340 const char * LOC = "FIELD<T,INTERLACING_TAG>::setValueIJ(int i, int j, T value) : ";
4343 valIndex = _support->getValIndFromGlobalNumber(i);
4345 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
4347 if ( getGaussPresence() )
4348 static_cast<ArrayGauss *>(_value)->setIJK(valIndex,j,k,value) ;
4350 static_cast<ArrayNoGauss *>(_value)->setIJK(valIndex,j,k,value) ;
4354 Set the value of i^{th} element and j^{th} component with the given one.
4356 template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValueIJByType(int i, int j, int t, T value) throw (MEDEXCEPTION)
4358 const char * LOC = "FIELD<T,INTERLACING_TAG>::setValueIJByType(int i, int j, int t, T value) : ";
4359 if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
4360 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
4362 if ( getGaussPresence() )
4363 return static_cast<ArrayNoByTypeGauss *>(_value)->setIJByType(i,j,t,value) ;
4365 return static_cast<ArrayNoByType *>(_value)->setIJByType(i,j,t,value) ;
4369 Set the value of component of k^{th} gauss points of i^{th} element and j^{th} component with the given one.
4371 template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValueIJKByType(int i, int j, int k, int t, T value) throw (MEDEXCEPTION)
4373 const char * LOC = "FIELD<T,INTERLACING_TAG>::setValueIJKByType(int i, int j, int t, int k, T value) : ";
4374 if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
4375 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
4377 if ( getGaussPresence() )
4378 return static_cast<ArrayNoByTypeGauss *>(_value)->setIJKByType(i,j,k,t,value) ;
4380 return static_cast<ArrayNoByType *>(_value)->setIJKByType(i,j,k,t,value) ;
4382 /*! \if MEDMEM_ug @} \endif */
4389 Fill array by using T_Analytic.
4390 WARNING : "this" must have allocated its array by setting this->_support and this->_numberOfComponents properly.
4391 Typically you should use it on a field built with constructor FIELD<T>::FIELD<T>(SUPPORT *,int nbOfComponents)
4393 template <class T, class INTERLACING_TAG>
4394 void FIELD<T, INTERLACING_TAG>::fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION)
4396 const char * LOC = "void FIELD<T, INTERLACING_TAG>::fillFromAnalytic(myFuncType f) : ";
4398 if (_support == (SUPPORT *) NULL)
4399 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No Support defined."));
4401 const GMESH * mesh = _support->getMesh();
4402 int spaceDim = mesh->getSpaceDimension();
4403 const double * coord;
4405 const double * bary;
4406 FIELD<double,FullInterlace> * barycenterField=0;
4408 double ** xyz=new double* [spaceDim];
4409 bool deallocateXyz=false;
4410 if(_support->getEntity()==MED_EN::MED_NODE)
4412 const MESH * unstructured = _support->getMesh()->convertInMESH();
4413 if (_support->isOnAllElements())
4415 coord=unstructured->getCoordinates(MED_EN::MED_NO_INTERLACE);
4416 for(i=0; i<spaceDim; i++)
4417 xyz[i]=(double *)coord+i*_numberOfValues;
4421 coord = unstructured->getCoordinates(MED_EN::MED_FULL_INTERLACE);
4422 const int * nodesNumber=_support->getNumber(MED_EN::MED_ALL_ELEMENTS);
4423 for(i=0; i<spaceDim; i++)
4424 xyz[i]=new double[_numberOfValues];
4426 for(i=0;i<_numberOfValues;i++)
4428 for(j=0;j<spaceDim;j++)
4429 xyz[j][i]=coord[(nodesNumber[i]-1)*spaceDim+j];
4432 unstructured->removeReference();
4436 barycenterField = mesh->getBarycenter(_support);
4437 bary = barycenterField->getValue();
4438 for(i=0; i<spaceDim; i++)
4439 xyz[i]=new double[_numberOfValues];
4441 for(i=0;i<_numberOfValues;i++) {
4442 for(j=0;j<spaceDim;j++)
4443 xyz[j][i]=bary[i*spaceDim+j];
4446 T* valsToSet=(T*)getValue();
4447 double *temp=new double[spaceDim];
4448 for(i=0;i<_numberOfValues;i++)
4450 for(j=0;j<spaceDim;j++)
4452 f(temp,valsToSet+i*_numberOfComponents);
4456 delete barycenterField;
4458 for(j=0;j<spaceDim;j++)
4464 Execute a function on _values on 'this' and put the result on a newly created field that has to be deallocated.
4465 WARNING : "this" must have allocated its array by setting this->_support and this->_numberOfComponents properly.
4466 Typically you should use it on a field built with constructor FIELD<T>::FIELD<T>(SUPPORT *,int nbOfComponents)
4468 template <class T, class INTERLACING_TAG>
4469 FIELD<T,INTERLACING_TAG> *FIELD<T, INTERLACING_TAG>::execFunc(int nbOfComponents,
4470 myFuncType2 f) throw (MEDEXCEPTION)
4472 FIELD<T,INTERLACING_TAG> *ret=new FIELD<T,INTERLACING_TAG>(_support,nbOfComponents);
4473 const T* valsInput=getValue();
4474 T* valsOutPut=(T*)ret->getValue();
4476 for(i=0;i<_numberOfValues;i++)
4477 f(valsInput+i*_numberOfComponents,valsOutPut+i*nbOfComponents);
4481 }//End namespace MEDMEM
4483 #endif /* FIELD_HXX */