Salome HOME
Building a version which will be tagged PreV2_0_0 working with KERNEL V1_4_0.
[modules/med.git] / src / MEDMEM / INTERPOLATION / MEDMEM_WrapperField.hxx
1 #ifndef MEDMEM_WRAPPER_FIELD_HXX
2 #define MEDMEM_WRAPPER_FIELD_HXX
3
4 #include "MEDMEM_Field.hxx"
5
6 #include <vector>
7
8 //////////////////////////////////////////////////////////////////
9 ///                                                            ///
10 ///                 DECLARATIONS ET CODE                       ///
11 ///                                                            ///
12 //////////////////////////////////////////////////////////////////
13
14 /*********************************************************/
15 /*                                                       */
16 /*        Template Arithmétiques de Valdhuizen           */
17 /*                                                       */
18 /*********************************************************/
19
20 // permet de faire des opérations algébriques sur des Wrappers_MED_Field sans faire d'allocations inutiles
21 // voir les articles de Valdhuizen pour la compréhension du processus
22
23 template <class TYPE> class Valeur;
24
25 struct Plus 
26 {
27 public :
28         static double apply(double a,double b) {return a+b;}
29 };
30
31 struct Multiply
32 {
33 public :
34         static double apply(double a,double b) {return a*b;}
35 };
36
37
38 template <typename Left,typename Op, typename Right> struct X
39 {
40         Left left;
41         Right right;
42         X(Left l,Right r):left(l),right(r){}
43         double operator[](int i)
44                 {
45                 return Op::apply(left[i],right[i]);
46                 }
47 };
48
49 template <typename Right> struct X<double,Multiply,Right>
50 {
51         double left;
52         Right right;
53         X(double l,Right r):left(l),right(r){}
54         double operator[](int i)
55                 {
56                 return Multiply::apply(left,right[i]);
57                 }
58 };
59
60 template <typename TYPE> X< Valeur<TYPE>,Plus,Valeur<TYPE> > operator+(Valeur<TYPE> v1,Valeur<TYPE> v2)
61 {
62 return X< Valeur<TYPE>,Plus,Valeur<TYPE> >(v1,v2);
63 }
64
65 template <typename TYPE> X< double,Multiply,Valeur<double> > operator*(TYPE sca,Valeur<TYPE> v)
66 {
67 return X< TYPE,Multiply,Valeur<TYPE> >(sca,v);
68 }
69
70 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)
71 {
72 return X< Valeur<TYPE>,Plus,X<L,O,R> >(v,expression);
73 }
74
75 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)
76 {
77 return X< X<L,O,R>,Plus,Valeur<TYPE> >(expression,v);
78 }
79
80 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 )
81 {
82 return X< X<Ll,Ol,Rl>,Plus,X<Lr,Or,Rr> >(el,er);
83 }
84
85 template <typename  L, typename O, typename R> X< double,Multiply,X<L,O,R> > operator*(double sca,X<L,O,R> expression)
86 {
87 return X< double,Multiply,X<L,O,R> >(sca,expression);
88 }
89
90 template <typename Left,typename Op,typename Right> X< double,Multiply,X<Left,Op,Right> > operator/(X<Left,Op,Right> l,double x)
91 {
92 return X< double,Multiply,X<Left,Op,Right> >(((double) 1/x),l);
93 }
94
95 /*********************************************************/
96 /*                                                       */
97 /*                    Classe Valeur                      */
98 /*                                                       */
99 /*********************************************************/
100
101 // Problèmes : les constructeurs par copie ne sont pas satisfaisants
102 // Valeur est symboliquement l'argument d'une classe formelle Vecteur<Valeur>
103 // elle peut etre un réel ou un pointeur sur réel, simulant un vecteur de vecteur
104
105 template <class TYPE> class Valeur
106 {
107 protected :
108         TYPE * valeurs;
109         int nbr_valeurs;
110         int a_detruire;
111 public :
112         Valeur():valeurs(NULL),a_detruire(0){}
113         Valeur(TYPE * val,int nv):valeurs(val),nbr_valeurs(nv),a_detruire(0){} // A VERIFIER
114         Valeur(int n):nbr_valeurs(n),a_detruire(1)
115                 {
116                 valeurs=new TYPE[nbr_valeurs];
117                 }
118         template <typename Left,typename Op,typename Right> Valeur(X<Left,Op,Right> expression)
119                 {
120                 for (int i=0;i<nbr_valeurs;i++) valeurs[i]=expression[i];
121                 }
122         template <typename Left,typename Op,typename Right> void operator=(X<Left,Op,Right> expression)
123                 {
124                 for (int i=0;i<nbr_valeurs;i++) valeurs[i]=expression[i];
125                 }
126         void operator=(Valeur v)
127                 {
128                 for (int i=0;i<nbr_valeurs;i++) valeurs[i]=v[i];
129                 }
130         Valeur(const Valeur &v):nbr_valeurs(v.nbr_valeurs)
131                 {
132                 if (v.a_detruire) 
133                         {
134                         a_detruire=1;
135                         valeurs=new TYPE[nbr_valeurs];
136                         for (int i=0;i<nbr_valeurs;i++) valeurs[i]=v.valeurs[i];
137                         }
138                 else
139                         {
140                         a_detruire=0;
141                         valeurs=v.valeurs;
142                         }
143                 }
144         ~Valeur(){if (a_detruire) delete [] valeurs;}
145         TYPE operator[](int i){return valeurs[i];}
146         int SIZE() const {return nbr_valeurs;}
147         double NormeAbs()
148                 {
149                 int i;
150                 double tmp=0;
151                 for (i=0;i<nbr_valeurs;i++) tmp+=fabs(valeurs[i]);
152                 return tmp;
153                 }
154
155 };
156
157 template <class TYPE> ostream &operator<<(ostream &os,Valeur<TYPE> v)
158         {       
159         os<<"("<<flush;
160         for (int i=0;i<v.SIZE();i++) os<<" "<<v[i]<<flush;
161         os<<" ) "<<flush;
162         return os;
163         }
164
165 /*********************************************************/
166 /*                                                       */
167 /*               Classe Wrapper_MED_Field                */
168 /*                                                       */
169 /*********************************************************/
170
171 // c'est la classe de Wrapping sur un objet FIELD<double> MEDMEMOIRE
172
173 class Wrapper_MED_Field
174 {
175 protected :
176         int nbr_valeurs;
177         int nbr_composantes;
178         double * valeurs;
179 public :
180         Wrapper_MED_Field():valeurs(NULL){}
181         Wrapper_MED_Field(int nv, int nc, double * v):nbr_valeurs(nv),nbr_composantes(nc),valeurs(v)
182                 {
183                 }
184         Wrapper_MED_Field(const FIELD<double> * medfield)
185                 {
186                 nbr_valeurs=medfield->getNumberOfValues();
187                 nbr_composantes=medfield->getNumberOfComponents();
188                 valeurs=const_cast<double *>(medfield->getValue(MED_FULL_INTERLACE));
189                 }
190         ~Wrapper_MED_Field(){}
191         inline Valeur<double> operator[](int i) 
192                 {
193                 return Valeur<double>(&valeurs[nbr_composantes*i],nbr_composantes);
194                 }
195         double * Get_Valeurs() {return valeurs;}
196         inline int Get_Nbr_Valeurs() const {return nbr_valeurs;}
197         inline int Get_Nbr_Composantes() const {return nbr_composantes;}
198         friend ostream & operator<<(ostream &os, Wrapper_MED_Field);
199 }; 
200
201 ostream & operator<<(ostream &os, Wrapper_MED_Field wmf)
202 {
203 for (int i=0;i<wmf.nbr_valeurs;i++) os<<"Wrapper_MED_Field["<<i<<"] = "<<wmf[i]<<endl;
204 return os;
205 }
206
207 #endif