Salome HOME
Merge from V6_main 01/04/2013
[modules/med.git] / src / MEDCalculator / MEDCalculatorDBSliceField.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCalculatorDBSliceField.hxx"
22 #include "MEDCalculatorDBRangeSelection.hxx"
23
24 #include "MEDLoader.hxx"
25
26 #include "MEDCouplingFieldDouble.hxx"
27 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
28
29 using namespace ParaMEDMEM;
30
31 MEDCalculatorDBSliceField::MEDCalculatorDBSliceField(int iter, int order):_iteration(iter),_order(order),_field(0),_work(0)
32 {
33 }
34
35 MEDCalculatorDBSliceField::MEDCalculatorDBSliceField(MEDCouplingFieldDouble *f):_field(f),_work(0)
36 {
37 }
38
39 void MEDCalculatorDBSliceField::setField(MEDCouplingFieldDouble *f) const
40 {
41   if(_field!=f)
42     {
43       if(_field)
44         _field->decrRef();
45       _field=f;
46     }
47 }
48
49 void MEDCalculatorDBSliceField::setName(const char *name)
50 {
51   _field->setName(name);
52 }
53
54 void MEDCalculatorDBSliceField::setDescription(const char *descr)
55 {
56   _field->setDescription(descr);
57 }
58
59 void MEDCalculatorDBSliceField::write(const char *fName, const std::string& n, const std::string& d) const throw(INTERP_KERNEL::Exception)
60 {
61   std::string kn=_field->getName();
62   std::string kd=_field->getDescription();
63   MEDCouplingFieldDouble *myF=const_cast<MEDCouplingFieldDouble *>(_field);
64   myF->setName(n.c_str());
65   myF->setDescription(d.c_str());
66   MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fName,_field);
67   myF->setName(kn.c_str());
68   myF->setDescription(kd.c_str());
69 }
70
71 const MEDCouplingMesh *MEDCalculatorDBSliceField::getMesh(TypeOfField type, const std::string& fname, const std::string& mname, const std::string& fieldName) const
72 {
73   MEDCouplingFieldDouble *f=getField(type,fname,mname,fieldName);
74   return f->getMesh();
75 }
76
77 MEDCalculatorDBSliceField::~MEDCalculatorDBSliceField()
78 {
79   if(_field)
80     _field->decrRef();
81   if(_work)
82     _work->decrRef();
83 }
84
85 MEDCouplingFieldDouble *MEDCalculatorDBSliceField::getField(TypeOfField type, const std::string& fname, const std::string& mname, const std::string& fieldName) const
86 {
87   if(!_field)
88     _field=MEDLoader::ReadField(type,fname.c_str(),mname.c_str(),0,fieldName.c_str(),_iteration,_order);
89   return _field;
90 }
91
92 /*!
93  * _field is expected to be already loaded !
94  */
95 MEDCouplingFieldDouble *MEDCalculatorDBSliceField::getFieldWithoutQuestion(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const
96 {
97   std::vector<int> tIds=thisC.getIds(sizeCThis);
98   return _field->keepSelectedComponents(tIds);
99 }
100
101 MEDCouplingFieldDouble *MEDCalculatorDBSliceField::buildCstFromThis(double val, int nbOfComp, const MEDCouplingFieldDouble *f) const
102 {
103   MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(f->getTypeOfField(),ONE_TIME);
104   ret->setMesh(f->getMesh());
105   ret->applyFunc(nbOfComp,val);
106   ret->copyTinyAttrFrom(f);
107   return ret;
108 }
109
110 void MEDCalculatorDBSliceField::assign(const MEDCalculatorDBSliceField* other, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
111                                     int sizeCOther, const MEDCalculatorDBRangeSelection& otherC)
112 {
113   std::vector<int> tIds=thisC.getIds(sizeCThis);
114   std::vector<int> oIds=otherC.getIds(sizeCOther);
115   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=other->_field->keepSelectedComponents(oIds);
116   _field->setSelectedComponents(f1,tIds);
117 }
118
119 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::add(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
120                                                     int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
121                                                     int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
122 {
123   if(cc!=0 || nc!=0)
124     throw INTERP_KERNEL::Exception("Slice::add : not implemented yet node/cell permutation !");
125   std::vector<int> tIds=thisC.getIds(sizeCThis);
126   std::vector<int> oIds=otherC.getIds(sizeCOther);
127   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
128   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
129   f2->setMesh(f1->getMesh());
130   MEDCouplingFieldDouble *f3=(*f1)+(*f2);
131   return new MEDCalculatorDBSliceField(f3);
132 }
133
134 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::substract(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
135                                                           int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
136                                                           int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
137 {
138   if(cc!=0 || nc!=0)
139     throw INTERP_KERNEL::Exception("Slice::substract : not implemented yet node/cell permutation !");
140   std::vector<int> tIds=thisC.getIds(sizeCThis);
141   std::vector<int> oIds=otherC.getIds(sizeCOther);
142   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
143   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
144   f2->setMesh(f1->getMesh());
145   MEDCouplingFieldDouble *f3=(*f1)-(*f2);
146   return new MEDCalculatorDBSliceField(f3);
147 }
148
149 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::multiply(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
150                                                          int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
151                                                          int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
152 {
153   if(cc!=0 || nc!=0)
154     throw INTERP_KERNEL::Exception("Slice::multiply : not implemented yet node/cell permutation !");
155   std::vector<int> tIds=thisC.getIds(sizeCThis);
156   std::vector<int> oIds=otherC.getIds(sizeCOther);
157   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
158   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
159   f2->setMesh(f1->getMesh());
160   MEDCouplingFieldDouble *f3=(*f1)*(*f2);
161   return new MEDCalculatorDBSliceField(f3);
162 }
163
164 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::divide(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
165                                                        int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
166                                                        int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
167 {
168   if(cc!=0 || nc!=0)
169     throw INTERP_KERNEL::Exception("Slice::divide : not implemented yet node/cell permutation !");
170   std::vector<int> tIds=thisC.getIds(sizeCThis);
171   std::vector<int> oIds=otherC.getIds(sizeCOther);
172   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
173   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
174   f2->setMesh(f1->getMesh());
175   MEDCouplingFieldDouble *f3=(*f1)/(*f2);
176   return new MEDCalculatorDBSliceField(f3);
177 }
178
179 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::dot(const MEDCalculatorDBSliceField* other, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
180                                                     int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
181 {
182   std::vector<int> tIds=thisC.getIds(sizeCThis);
183   std::vector<int> oIds=otherC.getIds(sizeCOther);
184   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
185   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
186   f2->setMesh(f1->getMesh());
187   MEDCouplingFieldDouble *f3=f1->dot(*f2);
188   return new MEDCalculatorDBSliceField(f3);
189 }
190
191 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::crossProduct(const MEDCalculatorDBSliceField* other, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
192                                                              int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
193 {
194   std::vector<int> tIds=thisC.getIds(sizeCThis);
195   std::vector<int> oIds=otherC.getIds(sizeCOther);
196   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
197   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
198   f2->setMesh(f1->getMesh());
199   MEDCouplingFieldDouble *f3=f1->crossProduct(*f2);
200   return new MEDCalculatorDBSliceField(f3);
201 }
202
203 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::doublyContractedProduct(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
204 {
205   std::vector<int> tIds=thisC.getIds(sizeCThis);
206   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
207   MEDCouplingFieldDouble *f2=f1->doublyContractedProduct();
208   return new MEDCalculatorDBSliceField(f2);
209 }
210
211 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::determinant(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
212 {
213   std::vector<int> tIds=thisC.getIds(sizeCThis);
214   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
215   MEDCouplingFieldDouble *f2=f1->determinant();
216   return new MEDCalculatorDBSliceField(f2);
217 }
218
219 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::eigenValues(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
220 {
221   std::vector<int> tIds=thisC.getIds(sizeCThis);
222   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
223   MEDCouplingFieldDouble *f2=f1->eigenValues();
224   return new MEDCalculatorDBSliceField(f2);
225 }
226
227 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::eigenVectors(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
228 {
229   std::vector<int> tIds=thisC.getIds(sizeCThis);
230   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
231   MEDCouplingFieldDouble *f2=f1->eigenVectors();
232   return new MEDCalculatorDBSliceField(f2);
233 }
234
235 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::inverse(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
236 {
237   std::vector<int> tIds=thisC.getIds(sizeCThis);
238   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
239   MEDCouplingFieldDouble *f2=f1->inverse();
240   return new MEDCalculatorDBSliceField(f2);
241 }
242
243 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::trace(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
244 {
245   std::vector<int> tIds=thisC.getIds(sizeCThis);
246   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
247   MEDCouplingFieldDouble *f2=f1->trace();
248   return new MEDCalculatorDBSliceField(f2);
249 }
250
251 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::deviator(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
252 {
253   std::vector<int> tIds=thisC.getIds(sizeCThis);
254   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
255   MEDCouplingFieldDouble *f2=f1->deviator();
256   return new MEDCalculatorDBSliceField(f2);
257 }
258
259 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::magnitude(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
260 {
261   std::vector<int> tIds=thisC.getIds(sizeCThis);
262   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
263   MEDCouplingFieldDouble *f2=f1->magnitude();
264   return new MEDCalculatorDBSliceField(f2);
265 }
266
267 void MEDCalculatorDBSliceField::applyFunc(const char *func, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC)
268 {
269   std::vector<int> tIds=thisC.getIds(sizeCThis);
270   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
271   f1->applyFunc(func);
272   _field->setSelectedComponents(f1,tIds);
273 }
274
275 bool MEDCalculatorDBSliceField::isEqual(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
276                                      int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
277                                      int sizeCOther, const MEDCalculatorDBRangeSelection& otherC, double prec) const
278 {
279   if(cc!=0 || nc!=0)
280     throw INTERP_KERNEL::Exception("Slice::isEqual : not implemented yet node/cell permutation !");
281   std::vector<int> tIds=thisC.getIds(sizeCThis);
282   std::vector<int> oIds=otherC.getIds(sizeCOther);
283   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
284   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
285   f2->setMesh(f1->getMesh());
286   return f1->isEqualWithoutConsideringStr(f2,0,prec);
287 }