src/INTERPOLATION/MEDMEM_WrapperField.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00002 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00003 // 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either 
00007 // version 2.1 of the License.
00008 // 
00009 // This library is distributed in the hope that it will be useful 
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
00012 // Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public  
00015 // License along with this library; if not, write to the Free Software 
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00017 //
00018 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00019 //
00020 #ifndef MEDMEM_WRAPPER_FIELD_HXX
00021 #define MEDMEM_WRAPPER_FIELD_HXX
00022 
00023 #include "MEDMEM_Field.hxx"
00024 
00025 #include <vector>
00026 
00032 
00033 /*********************************************************/
00034 /*                                                       */
00035 /*        Template Arithmétiques de Valdhuizen           */
00036 /*                                                       */
00037 /*********************************************************/
00038 
00039 // permet de faire des opérations algébriques sur des Wrappers_MED_Field sans faire d'allocations inutiles
00040 // voir les articles de Valdhuizen pour la compréhension du processus
00041 
00042 struct Plus 
00043 {
00044 public :
00045      static double apply(double a,double b) {return a+b;}
00046 };
00047 
00048 struct Multiply
00049 {
00050 public :
00051      static double apply(double a,double b) {return a*b;}
00052 };
00053 
00054 
00055 template <typename Left,typename Op, typename Right> struct X
00056 {
00057      Left left;
00058      Right right;
00059      X(Left l,Right r):left(l),right(r){}
00060      double operator[](int i)
00061           {
00062           return Op::apply(left[i],right[i]);
00063           }
00064 };
00065 
00066 template <typename Right> struct X<double,Multiply,Right>
00067 {
00068      double left;
00069      Right right;
00070      X(double l,Right r):left(l),right(r){}
00071      double operator[](int i)
00072           {
00073           return Multiply::apply(left,right[i]);
00074           }
00075 };
00076 
00077 template <class TYPE> class Valeur
00078 {
00079 protected :
00080      TYPE * valeurs;
00081      int nbr_valeurs;
00082      int a_detruire;
00083 public :
00084      Valeur();
00085      Valeur(TYPE * val,int nv);
00086      Valeur(int n);
00087      template <typename Left,typename Op,typename Right> Valeur(X<Left,Op,Right> expression);
00088      template <typename Left,typename Op,typename Right> void operator=(X<Left,Op,Right> expression);
00089      void operator=(Valeur v);
00090      Valeur(const Valeur &v);
00091      ~Valeur();
00092      TYPE operator[](int i);
00093      int SIZE() const;
00094      double NormeAbs();
00095 };
00096 
00097 template <typename TYPE> X< Valeur<TYPE>,Plus,Valeur<TYPE> > operator+(Valeur<TYPE> v1,Valeur<TYPE> v2)
00098 {
00099 return X< Valeur<TYPE>,Plus,Valeur<TYPE> >(v1,v2);
00100 }
00101 
00102 template <typename TYPE> X< double,Multiply,Valeur<double> > operator*(TYPE sca,Valeur<TYPE> v)
00103 {
00104 return X< TYPE,Multiply,Valeur<TYPE> >(sca,v);
00105 }
00106 
00107 template <typename TYPE,typename  L, typename O, typename R> X< Valeur<TYPE>,Plus,X<L,O,R> > operator+(Valeur<TYPE> v,X<L,O,R> expression)
00108 {
00109 return X< Valeur<TYPE>,Plus,X<L,O,R> >(v,expression);
00110 }
00111 
00112 template <typename TYPE,typename  L, typename O, typename R> X< X<L,O,R>,Plus,Valeur<TYPE> > operator+(X<L,O,R> expression,Valeur<TYPE> v)
00113 {
00114 return X< X<L,O,R>,Plus,Valeur<TYPE> >(expression,v);
00115 }
00116 
00117 template <typename  Ll, typename  Ol, typename  Rl,typename  Lr, typename  Or, typename  Rr> X< X<Ll,Ol,Rl>,Plus, X<Lr,Or,Rr> > operator+(X<Ll,Ol,Rl> el, X<Lr,Or,Rr> er )
00118 {
00119 return X< X<Ll,Ol,Rl>,Plus,X<Lr,Or,Rr> >(el,er);
00120 }
00121 
00122 template <typename  L, typename O, typename R> X< double,Multiply,X<L,O,R> > operator*(double sca,X<L,O,R> expression)
00123 {
00124 return X< double,Multiply,X<L,O,R> >(sca,expression);
00125 }
00126 
00127 template <typename Left,typename Op,typename Right> X< double,Multiply,X<Left,Op,Right> > operator/(X<Left,Op,Right> l,double x)
00128 {
00129 return X< double,Multiply,X<Left,Op,Right> >(((double) 1/x),l);
00130 }
00131 
00132 /*********************************************************/
00133 /*                                                       */
00134 /*                    Classe Valeur                      */
00135 /*                                                       */
00136 /*********************************************************/
00137 
00138 // Problèmes : les constructeurs par copie ne sont pas satisfaisants
00139 // Valeur est symboliquement l'argument d'une classe formelle Vecteur<Valeur>
00140 // elle peut etre un réel ou un pointeur sur réel, simulant un vecteur de vecteur
00141 
00142 template <class TYPE> Valeur<TYPE>::Valeur():valeurs(NULL),a_detruire(0){}
00143 template <class TYPE> Valeur<TYPE>::Valeur(TYPE * val,int nv):valeurs(val),nbr_valeurs(nv),a_detruire(0){} // A VERIFIER
00144 template <class TYPE> Valeur<TYPE>::Valeur(int n):nbr_valeurs(n),a_detruire(1)
00145 {
00146   valeurs=new TYPE[nbr_valeurs];
00147 }
00148 template <class TYPE> template <typename Left,typename Op,typename Right> Valeur<TYPE>::Valeur(X<Left,Op,Right> expression)
00149 {
00150   for (int i=0;i<nbr_valeurs;i++) valeurs[i]=expression[i];
00151 }
00152 template <class TYPE> template <typename Left,typename Op,typename Right> void Valeur<TYPE>::operator=(X<Left,Op,Right> expression)
00153 {
00154   for (int i=0;i<nbr_valeurs;i++) valeurs[i]=expression[i];
00155 }
00156 template <class TYPE> void Valeur<TYPE>::operator=(Valeur v)
00157 {
00158   for (int i=0;i<nbr_valeurs;i++) valeurs[i]=v[i];
00159 }
00160 template <class TYPE> Valeur<TYPE>::Valeur(const Valeur &v):nbr_valeurs(v.nbr_valeurs)
00161 {
00162   if (v.a_detruire) 
00163     {
00164       a_detruire=1;
00165       valeurs=new TYPE[nbr_valeurs];
00166       for (int i=0;i<nbr_valeurs;i++) valeurs[i]=v.valeurs[i];
00167     }
00168   else
00169     {
00170       a_detruire=0;
00171       valeurs=v.valeurs;
00172     }
00173 }
00174 template <class TYPE> Valeur<TYPE>::~Valeur(){if (a_detruire) delete [] valeurs;}
00175 template <class TYPE> TYPE Valeur<TYPE>::operator[](int i){return valeurs[i];}
00176 template <class TYPE> int Valeur<TYPE>::SIZE() const {return nbr_valeurs;}
00177 template <class TYPE> double Valeur<TYPE>::NormeAbs()
00178 {
00179   int i;
00180   double tmp=0;
00181   for (i=0;i<nbr_valeurs;i++) tmp+=fabs(valeurs[i]);
00182   return tmp;
00183 }
00184 
00185 template <class TYPE> ostream &operator<<(ostream &os,Valeur<TYPE> v)
00186      {    
00187      os<<"("<<flush;
00188      for (int i=0;i<v.SIZE();i++) os<<" "<<v[i]<<flush;
00189      os<<" ) "<<flush;
00190      return os;
00191      }
00192 
00193 /*********************************************************/
00194 /*                                                       */
00195 /*               Classe Wrapper_MED_Field                */
00196 /*                                                       */
00197 /*********************************************************/
00198 
00199 // c'est la classe de Wrapping sur un objet FIELD<double> MEDMEMOIRE
00200 
00201 class Wrapper_MED_Field
00202 {
00203 protected :
00204      int nbr_valeurs;
00205      int nbr_composantes;
00206      double * valeurs;
00207 public :
00208      Wrapper_MED_Field():valeurs(NULL){}
00209      Wrapper_MED_Field(int nv, int nc, double * v):nbr_valeurs(nv),nbr_composantes(nc),valeurs(v)
00210           {
00211           }
00212      Wrapper_MED_Field(const MEDMEM::FIELD<double,MEDMEM::FullInterlace> * medfield)
00213           {
00214           nbr_valeurs=medfield->getNumberOfValues();
00215           nbr_composantes=medfield->getNumberOfComponents();
00216           valeurs=const_cast<double *>(medfield->getValue());
00217           }
00218      ~Wrapper_MED_Field(){}
00219      inline Valeur<double> operator[](int i) 
00220           {
00221           return Valeur<double>(&valeurs[nbr_composantes*i],nbr_composantes);
00222           }
00223      double * Get_Valeurs() {return valeurs;}
00224      inline int Get_Nbr_Valeurs() const {return nbr_valeurs;}
00225      inline int Get_Nbr_Composantes() const {return nbr_composantes;}
00226      friend ostream & operator<<(ostream &os, Wrapper_MED_Field);
00227 }; 
00228 
00229 inline ostream & operator<<(ostream &os, Wrapper_MED_Field wmf)
00230 {
00231 for (int i=0;i<wmf.nbr_valeurs;i++) os<<"Wrapper_MED_Field["<<i<<"] = "<<wmf[i]<<endl;
00232 return os;
00233 }
00234 
00235 #endif