Salome HOME
Copyrights update
[modules/med.git] / src / INTERPOLATION / MEDMEM_WrapperField.hxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/
19 //
20 #ifndef MEDMEM_WRAPPER_FIELD_HXX
21 #define MEDMEM_WRAPPER_FIELD_HXX
22
23 #include "MEDMEM_Field.hxx"
24
25 #include <vector>
26
27 //////////////////////////////////////////////////////////////////
28 ///                                                            ///
29 ///                 DECLARATIONS ET CODE                       ///
30 ///                                                            ///
31 //////////////////////////////////////////////////////////////////
32
33 /*********************************************************/
34 /*                                                       */
35 /*        Template Arithmétiques de Valdhuizen           */
36 /*                                                       */
37 /*********************************************************/
38
39 // permet de faire des opérations algébriques sur des Wrappers_MED_Field sans faire d'allocations inutiles
40 // voir les articles de Valdhuizen pour la compréhension du processus
41
42 template <class TYPE> class Valeur;
43
44 struct Plus 
45 {
46 public :
47         static double apply(double a,double b) {return a+b;}
48 };
49
50 struct Multiply
51 {
52 public :
53         static double apply(double a,double b) {return a*b;}
54 };
55
56
57 template <typename Left,typename Op, typename Right> struct X
58 {
59         Left left;
60         Right right;
61         X(Left l,Right r):left(l),right(r){}
62         double operator[](int i)
63                 {
64                 return Op::apply(left[i],right[i]);
65                 }
66 };
67
68 template <typename Right> struct X<double,Multiply,Right>
69 {
70         double left;
71         Right right;
72         X(double l,Right r):left(l),right(r){}
73         double operator[](int i)
74                 {
75                 return Multiply::apply(left,right[i]);
76                 }
77 };
78
79 template <typename TYPE> X< Valeur<TYPE>,Plus,Valeur<TYPE> > operator+(Valeur<TYPE> v1,Valeur<TYPE> v2)
80 {
81 return X< Valeur<TYPE>,Plus,Valeur<TYPE> >(v1,v2);
82 }
83
84 template <typename TYPE> X< double,Multiply,Valeur<double> > operator*(TYPE sca,Valeur<TYPE> v)
85 {
86 return X< TYPE,Multiply,Valeur<TYPE> >(sca,v);
87 }
88
89 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)
90 {
91 return X< Valeur<TYPE>,Plus,X<L,O,R> >(v,expression);
92 }
93
94 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)
95 {
96 return X< X<L,O,R>,Plus,Valeur<TYPE> >(expression,v);
97 }
98
99 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 )
100 {
101 return X< X<Ll,Ol,Rl>,Plus,X<Lr,Or,Rr> >(el,er);
102 }
103
104 template <typename  L, typename O, typename R> X< double,Multiply,X<L,O,R> > operator*(double sca,X<L,O,R> expression)
105 {
106 return X< double,Multiply,X<L,O,R> >(sca,expression);
107 }
108
109 template <typename Left,typename Op,typename Right> X< double,Multiply,X<Left,Op,Right> > operator/(X<Left,Op,Right> l,double x)
110 {
111 return X< double,Multiply,X<Left,Op,Right> >(((double) 1/x),l);
112 }
113
114 /*********************************************************/
115 /*                                                       */
116 /*                    Classe Valeur                      */
117 /*                                                       */
118 /*********************************************************/
119
120 // Problèmes : les constructeurs par copie ne sont pas satisfaisants
121 // Valeur est symboliquement l'argument d'une classe formelle Vecteur<Valeur>
122 // elle peut etre un réel ou un pointeur sur réel, simulant un vecteur de vecteur
123
124 template <class TYPE> class Valeur
125 {
126 protected :
127         TYPE * valeurs;
128         int nbr_valeurs;
129         int a_detruire;
130 public :
131         Valeur():valeurs(NULL),a_detruire(0){}
132         Valeur(TYPE * val,int nv):valeurs(val),nbr_valeurs(nv),a_detruire(0){} // A VERIFIER
133         Valeur(int n):nbr_valeurs(n),a_detruire(1)
134                 {
135                 valeurs=new TYPE[nbr_valeurs];
136                 }
137         template <typename Left,typename Op,typename Right> Valeur(X<Left,Op,Right> expression)
138                 {
139                 for (int i=0;i<nbr_valeurs;i++) valeurs[i]=expression[i];
140                 }
141         template <typename Left,typename Op,typename Right> void operator=(X<Left,Op,Right> expression)
142                 {
143                 for (int i=0;i<nbr_valeurs;i++) valeurs[i]=expression[i];
144                 }
145         void operator=(Valeur v)
146                 {
147                 for (int i=0;i<nbr_valeurs;i++) valeurs[i]=v[i];
148                 }
149         Valeur(const Valeur &v):nbr_valeurs(v.nbr_valeurs)
150                 {
151                 if (v.a_detruire) 
152                         {
153                         a_detruire=1;
154                         valeurs=new TYPE[nbr_valeurs];
155                         for (int i=0;i<nbr_valeurs;i++) valeurs[i]=v.valeurs[i];
156                         }
157                 else
158                         {
159                         a_detruire=0;
160                         valeurs=v.valeurs;
161                         }
162                 }
163         ~Valeur(){if (a_detruire) delete [] valeurs;}
164         TYPE operator[](int i){return valeurs[i];}
165         int SIZE() const {return nbr_valeurs;}
166         double NormeAbs()
167                 {
168                 int i;
169                 double tmp=0;
170                 for (i=0;i<nbr_valeurs;i++) tmp+=fabs(valeurs[i]);
171                 return tmp;
172                 }
173
174 };
175
176 template <class TYPE> ostream &operator<<(ostream &os,Valeur<TYPE> v)
177         {       
178         os<<"("<<flush;
179         for (int i=0;i<v.SIZE();i++) os<<" "<<v[i]<<flush;
180         os<<" ) "<<flush;
181         return os;
182         }
183
184 /*********************************************************/
185 /*                                                       */
186 /*               Classe Wrapper_MED_Field                */
187 /*                                                       */
188 /*********************************************************/
189
190 // c'est la classe de Wrapping sur un objet FIELD<double> MEDMEMOIRE
191
192 class Wrapper_MED_Field
193 {
194 protected :
195         int nbr_valeurs;
196         int nbr_composantes;
197         double * valeurs;
198 public :
199         Wrapper_MED_Field():valeurs(NULL){}
200         Wrapper_MED_Field(int nv, int nc, double * v):nbr_valeurs(nv),nbr_composantes(nc),valeurs(v)
201                 {
202                 }
203         Wrapper_MED_Field(const MEDMEM::FIELD<double> * medfield)
204                 {
205                 nbr_valeurs=medfield->getNumberOfValues();
206                 nbr_composantes=medfield->getNumberOfComponents();
207                 valeurs=const_cast<double *>(medfield->getValue(MED_EN::MED_FULL_INTERLACE));
208                 }
209         ~Wrapper_MED_Field(){}
210         inline Valeur<double> operator[](int i) 
211                 {
212                 return Valeur<double>(&valeurs[nbr_composantes*i],nbr_composantes);
213                 }
214         double * Get_Valeurs() {return valeurs;}
215         inline int Get_Nbr_Valeurs() const {return nbr_valeurs;}
216         inline int Get_Nbr_Composantes() const {return nbr_composantes;}
217         friend ostream & operator<<(ostream &os, Wrapper_MED_Field);
218 }; 
219
220 inline ostream & operator<<(ostream &os, Wrapper_MED_Field wmf)
221 {
222 for (int i=0;i<wmf.nbr_valeurs;i++) os<<"Wrapper_MED_Field["<<i<<"] = "<<wmf[i]<<endl;
223 return os;
224 }
225
226 #endif