Salome HOME
1st step.
[modules/med.git] / src / MEDCalculator / MEDCalculatorDBSliceField.cxx
1 // Copyright (C) 2007-2015  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, or (at your option) any later version.
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 MEDCoupling;
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 std::size_t MEDCalculatorDBSliceField::getHeapMemorySizeWithoutChildren() const
40 {
41   return 0;
42 }
43
44 std::vector<const BigMemoryObject *> MEDCalculatorDBSliceField::getDirectChildrenWithNull() const
45 {
46   return std::vector<const BigMemoryObject *>();
47 }
48
49 void MEDCalculatorDBSliceField::setField(MEDCouplingFieldDouble *f) const
50 {
51   if(_field!=f)
52     {
53       if(_field)
54         _field->decrRef();
55       _field=f;
56     }
57 }
58
59 void MEDCalculatorDBSliceField::setName(const char *name)
60 {
61   _field->setName(name);
62 }
63
64 void MEDCalculatorDBSliceField::setDescription(const char *descr)
65 {
66   _field->setDescription(descr);
67 }
68
69 void MEDCalculatorDBSliceField::write(const char *fName, const std::string& n, const std::string& d) const throw(INTERP_KERNEL::Exception)
70 {
71   std::string kn=_field->getName();
72   std::string kd=_field->getDescription();
73   MEDCouplingFieldDouble *myF=const_cast<MEDCouplingFieldDouble *>(_field);
74   myF->setName(n.c_str());
75   myF->setDescription(d.c_str());
76   WriteFieldUsingAlreadyWrittenMesh(fName,_field);
77   myF->setName(kn.c_str());
78   myF->setDescription(kd.c_str());
79 }
80
81 const MEDCouplingMesh *MEDCalculatorDBSliceField::getMesh(TypeOfField type, const std::string& fname, const std::string& mname, const std::string& fieldName) const
82 {
83   MEDCouplingFieldDouble *f=getField(type,fname,mname,fieldName);
84   return f->getMesh();
85 }
86
87 MEDCalculatorDBSliceField::~MEDCalculatorDBSliceField()
88 {
89   if(_field)
90     _field->decrRef();
91   if(_work)
92     _work->decrRef();
93 }
94
95 MEDCouplingFieldDouble *MEDCalculatorDBSliceField::getField(TypeOfField type, const std::string& fname, const std::string& mname, const std::string& fieldName) const
96 {
97   if(!_field)
98     _field=ReadField(type,fname.c_str(),mname.c_str(),0,fieldName.c_str(),_iteration,_order);
99   return _field;
100 }
101
102 /*!
103  * _field is expected to be already loaded !
104  */
105 MEDCouplingFieldDouble *MEDCalculatorDBSliceField::getFieldWithoutQuestion(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const
106 {
107   std::vector<int> tIds=thisC.getIds(sizeCThis);
108   return _field->keepSelectedComponents(tIds);
109 }
110
111 MEDCouplingFieldDouble *MEDCalculatorDBSliceField::buildCstFromThis(double val, int nbOfComp, const MEDCouplingFieldDouble *f) const
112 {
113   MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(f->getTypeOfField(),ONE_TIME);
114   ret->setMesh(f->getMesh());
115   ret->applyFunc(nbOfComp,val);
116   ret->copyTinyAttrFrom(f);
117   return ret;
118 }
119
120 void MEDCalculatorDBSliceField::assign(const MEDCalculatorDBSliceField* other, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
121                                     int sizeCOther, const MEDCalculatorDBRangeSelection& otherC)
122 {
123   std::vector<int> tIds=thisC.getIds(sizeCThis);
124   std::vector<int> oIds=otherC.getIds(sizeCOther);
125   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=other->_field->keepSelectedComponents(oIds);
126   _field->setSelectedComponents(f1,tIds);
127 }
128
129 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::add(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
130                                                     int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
131                                                     int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
132 {
133   if(cc!=0 || nc!=0)
134     throw INTERP_KERNEL::Exception("Slice::add : not implemented yet node/cell permutation !");
135   std::vector<int> tIds=thisC.getIds(sizeCThis);
136   std::vector<int> oIds=otherC.getIds(sizeCOther);
137   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
138   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
139   f2->setMesh(f1->getMesh());
140   MEDCouplingFieldDouble *f3=(*f1)+(*f2);
141   return new MEDCalculatorDBSliceField(f3);
142 }
143
144 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::substract(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
145                                                           int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
146                                                           int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
147 {
148   if(cc!=0 || nc!=0)
149     throw INTERP_KERNEL::Exception("Slice::substract : not implemented yet node/cell permutation !");
150   std::vector<int> tIds=thisC.getIds(sizeCThis);
151   std::vector<int> oIds=otherC.getIds(sizeCOther);
152   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
153   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
154   f2->setMesh(f1->getMesh());
155   MEDCouplingFieldDouble *f3=(*f1)-(*f2);
156   return new MEDCalculatorDBSliceField(f3);
157 }
158
159 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::multiply(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
160                                                          int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
161                                                          int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
162 {
163   if(cc!=0 || nc!=0)
164     throw INTERP_KERNEL::Exception("Slice::multiply : not implemented yet node/cell permutation !");
165   std::vector<int> tIds=thisC.getIds(sizeCThis);
166   std::vector<int> oIds=otherC.getIds(sizeCOther);
167   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
168   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
169   f2->setMesh(f1->getMesh());
170   MEDCouplingFieldDouble *f3=(*f1)*(*f2);
171   return new MEDCalculatorDBSliceField(f3);
172 }
173
174 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::divide(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
175                                                        int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
176                                                        int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
177 {
178   if(cc!=0 || nc!=0)
179     throw INTERP_KERNEL::Exception("Slice::divide : not implemented yet node/cell permutation !");
180   std::vector<int> tIds=thisC.getIds(sizeCThis);
181   std::vector<int> oIds=otherC.getIds(sizeCOther);
182   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
183   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
184   f2->setMesh(f1->getMesh());
185   MEDCouplingFieldDouble *f3=(*f1)/(*f2);
186   return new MEDCalculatorDBSliceField(f3);
187 }
188
189 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::dot(const MEDCalculatorDBSliceField* other, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
190                                                     int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
191 {
192   std::vector<int> tIds=thisC.getIds(sizeCThis);
193   std::vector<int> oIds=otherC.getIds(sizeCOther);
194   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
195   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
196   f2->setMesh(f1->getMesh());
197   MEDCouplingFieldDouble *f3=f1->dot(*f2);
198   return new MEDCalculatorDBSliceField(f3);
199 }
200
201 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::crossProduct(const MEDCalculatorDBSliceField* other, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
202                                                              int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
203 {
204   std::vector<int> tIds=thisC.getIds(sizeCThis);
205   std::vector<int> oIds=otherC.getIds(sizeCOther);
206   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
207   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
208   f2->setMesh(f1->getMesh());
209   MEDCouplingFieldDouble *f3=f1->crossProduct(*f2);
210   return new MEDCalculatorDBSliceField(f3);
211 }
212
213 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::doublyContractedProduct(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
214 {
215   std::vector<int> tIds=thisC.getIds(sizeCThis);
216   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
217   MEDCouplingFieldDouble *f2=f1->doublyContractedProduct();
218   return new MEDCalculatorDBSliceField(f2);
219 }
220
221 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::determinant(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
222 {
223   std::vector<int> tIds=thisC.getIds(sizeCThis);
224   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
225   MEDCouplingFieldDouble *f2=f1->determinant();
226   return new MEDCalculatorDBSliceField(f2);
227 }
228
229 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::eigenValues(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
230 {
231   std::vector<int> tIds=thisC.getIds(sizeCThis);
232   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
233   MEDCouplingFieldDouble *f2=f1->eigenValues();
234   return new MEDCalculatorDBSliceField(f2);
235 }
236
237 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::eigenVectors(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
238 {
239   std::vector<int> tIds=thisC.getIds(sizeCThis);
240   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
241   MEDCouplingFieldDouble *f2=f1->eigenVectors();
242   return new MEDCalculatorDBSliceField(f2);
243 }
244
245 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::inverse(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
246 {
247   std::vector<int> tIds=thisC.getIds(sizeCThis);
248   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
249   MEDCouplingFieldDouble *f2=f1->inverse();
250   return new MEDCalculatorDBSliceField(f2);
251 }
252
253 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::trace(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
254 {
255   std::vector<int> tIds=thisC.getIds(sizeCThis);
256   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
257   MEDCouplingFieldDouble *f2=f1->trace();
258   return new MEDCalculatorDBSliceField(f2);
259 }
260
261 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::deviator(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
262 {
263   std::vector<int> tIds=thisC.getIds(sizeCThis);
264   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
265   MEDCouplingFieldDouble *f2=f1->deviator();
266   return new MEDCalculatorDBSliceField(f2);
267 }
268
269 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::magnitude(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
270 {
271   std::vector<int> tIds=thisC.getIds(sizeCThis);
272   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
273   MEDCouplingFieldDouble *f2=f1->magnitude();
274   return new MEDCalculatorDBSliceField(f2);
275 }
276
277 void MEDCalculatorDBSliceField::applyFunc(const char *func, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC)
278 {
279   std::vector<int> tIds=thisC.getIds(sizeCThis);
280   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
281   f1->applyFunc(func);
282   _field->setSelectedComponents(f1,tIds);
283 }
284
285 bool MEDCalculatorDBSliceField::isEqual(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
286                                      int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
287                                      int sizeCOther, const MEDCalculatorDBRangeSelection& otherC, double prec) const
288 {
289   if(cc!=0 || nc!=0)
290     throw INTERP_KERNEL::Exception("Slice::isEqual : not implemented yet node/cell permutation !");
291   std::vector<int> tIds=thisC.getIds(sizeCThis);
292   std::vector<int> oIds=otherC.getIds(sizeCOther);
293   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
294   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
295   f2->setMesh(f1->getMesh());
296   return f1->isEqualWithoutConsideringStr(f2,0,prec);
297 }