Salome HOME
4a7ced0e7c051e4ecf9b7e53a4acf84b5e5bd4aa
[modules/med.git] / src / MEDCalculator / MEDCalculatorDBSliceField.cxx
1 // Copyright (C) 2007-2019  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 "MCAuto.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     {
99       MCAuto<MEDCouplingField> tmpp(ReadField(type,fname.c_str(),mname.c_str(),0,fieldName.c_str(),_iteration,_order));
100       MCAuto<MEDCouplingFieldDouble> tmp(DynamicCast<MEDCouplingField,MEDCouplingFieldDouble>(tmpp));
101       _field=tmp.retn();
102     }
103   return _field;
104 }
105
106 /*!
107  * _field is expected to be already loaded !
108  */
109 MEDCouplingFieldDouble *MEDCalculatorDBSliceField::getFieldWithoutQuestion(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const
110 {
111   std::vector<int> tIds=thisC.getIds(sizeCThis);
112   return _field->keepSelectedComponents(tIds);
113 }
114
115 MEDCouplingFieldDouble *MEDCalculatorDBSliceField::buildCstFromThis(double val, int nbOfComp, const MEDCouplingFieldDouble *f) const
116 {
117   MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(f->getTypeOfField(),ONE_TIME);
118   ret->setMesh(f->getMesh());
119   ret->applyFunc(nbOfComp,val);
120   ret->copyTinyAttrFrom(f);
121   return ret;
122 }
123
124 void MEDCalculatorDBSliceField::assign(const MEDCalculatorDBSliceField* other, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
125                                     int sizeCOther, const MEDCalculatorDBRangeSelection& otherC)
126 {
127   std::vector<int> tIds=thisC.getIds(sizeCThis);
128   std::vector<int> oIds=otherC.getIds(sizeCOther);
129   MCAuto<MEDCouplingFieldDouble> f1=other->_field->keepSelectedComponents(oIds);
130   _field->setSelectedComponents(f1,tIds);
131 }
132
133 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::add(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
134                                                     int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
135                                                     int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
136 {
137   if(cc!=0 || nc!=0)
138     throw INTERP_KERNEL::Exception("Slice::add : not implemented yet node/cell permutation !");
139   std::vector<int> tIds=thisC.getIds(sizeCThis);
140   std::vector<int> oIds=otherC.getIds(sizeCOther);
141   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
142   MCAuto<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
143   f2->setMesh(f1->getMesh());
144   MEDCouplingFieldDouble *f3=(*f1)+(*f2);
145   return new MEDCalculatorDBSliceField(f3);
146 }
147
148 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::substract(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
149                                                           int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
150                                                           int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
151 {
152   if(cc!=0 || nc!=0)
153     throw INTERP_KERNEL::Exception("Slice::substract : not implemented yet node/cell permutation !");
154   std::vector<int> tIds=thisC.getIds(sizeCThis);
155   std::vector<int> oIds=otherC.getIds(sizeCOther);
156   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
157   MCAuto<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
158   f2->setMesh(f1->getMesh());
159   MEDCouplingFieldDouble *f3=(*f1)-(*f2);
160   return new MEDCalculatorDBSliceField(f3);
161 }
162
163 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::multiply(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
164                                                          int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
165                                                          int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
166 {
167   if(cc!=0 || nc!=0)
168     throw INTERP_KERNEL::Exception("Slice::multiply : not implemented yet node/cell permutation !");
169   std::vector<int> tIds=thisC.getIds(sizeCThis);
170   std::vector<int> oIds=otherC.getIds(sizeCOther);
171   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
172   MCAuto<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
173   f2->setMesh(f1->getMesh());
174   MEDCouplingFieldDouble *f3=(*f1)*(*f2);
175   return new MEDCalculatorDBSliceField(f3);
176 }
177
178 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::divide(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
179                                                        int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
180                                                        int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
181 {
182   if(cc!=0 || nc!=0)
183     throw INTERP_KERNEL::Exception("Slice::divide : not implemented yet node/cell permutation !");
184   std::vector<int> tIds=thisC.getIds(sizeCThis);
185   std::vector<int> oIds=otherC.getIds(sizeCOther);
186   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
187   MCAuto<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
188   f2->setMesh(f1->getMesh());
189   MEDCouplingFieldDouble *f3=(*f1)/(*f2);
190   return new MEDCalculatorDBSliceField(f3);
191 }
192
193 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::dot(const MEDCalculatorDBSliceField* other, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
194                                                     int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
195 {
196   std::vector<int> tIds=thisC.getIds(sizeCThis);
197   std::vector<int> oIds=otherC.getIds(sizeCOther);
198   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
199   MCAuto<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
200   f2->setMesh(f1->getMesh());
201   MEDCouplingFieldDouble *f3=f1->dot(*f2);
202   return new MEDCalculatorDBSliceField(f3);
203 }
204
205 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::crossProduct(const MEDCalculatorDBSliceField* other, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
206                                                              int sizeCOther, const MEDCalculatorDBRangeSelection& otherC) const
207 {
208   std::vector<int> tIds=thisC.getIds(sizeCThis);
209   std::vector<int> oIds=otherC.getIds(sizeCOther);
210   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
211   MCAuto<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
212   f2->setMesh(f1->getMesh());
213   MEDCouplingFieldDouble *f3=f1->crossProduct(*f2);
214   return new MEDCalculatorDBSliceField(f3);
215 }
216
217 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::doublyContractedProduct(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
218 {
219   std::vector<int> tIds=thisC.getIds(sizeCThis);
220   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
221   MEDCouplingFieldDouble *f2=f1->doublyContractedProduct();
222   return new MEDCalculatorDBSliceField(f2);
223 }
224
225 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::determinant(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
226 {
227   std::vector<int> tIds=thisC.getIds(sizeCThis);
228   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
229   MEDCouplingFieldDouble *f2=f1->determinant();
230   return new MEDCalculatorDBSliceField(f2);
231 }
232
233 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::eigenValues(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
234 {
235   std::vector<int> tIds=thisC.getIds(sizeCThis);
236   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
237   MEDCouplingFieldDouble *f2=f1->eigenValues();
238   return new MEDCalculatorDBSliceField(f2);
239 }
240
241 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::eigenVectors(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
242 {
243   std::vector<int> tIds=thisC.getIds(sizeCThis);
244   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
245   MEDCouplingFieldDouble *f2=f1->eigenVectors();
246   return new MEDCalculatorDBSliceField(f2);
247 }
248
249 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::inverse(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
250 {
251   std::vector<int> tIds=thisC.getIds(sizeCThis);
252   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
253   MEDCouplingFieldDouble *f2=f1->inverse();
254   return new MEDCalculatorDBSliceField(f2);
255 }
256
257 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::trace(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
258 {
259   std::vector<int> tIds=thisC.getIds(sizeCThis);
260   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
261   MEDCouplingFieldDouble *f2=f1->trace();
262   return new MEDCalculatorDBSliceField(f2);
263 }
264
265 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::deviator(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
266 {
267   std::vector<int> tIds=thisC.getIds(sizeCThis);
268   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
269   MEDCouplingFieldDouble *f2=f1->deviator();
270   return new MEDCalculatorDBSliceField(f2);
271 }
272
273 MEDCalculatorDBSliceField *MEDCalculatorDBSliceField::magnitude(int sizeCThis, const MEDCalculatorDBRangeSelection& thisC) const throw(INTERP_KERNEL::Exception)
274 {
275   std::vector<int> tIds=thisC.getIds(sizeCThis);
276   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
277   MEDCouplingFieldDouble *f2=f1->magnitude();
278   return new MEDCalculatorDBSliceField(f2);
279 }
280
281 void MEDCalculatorDBSliceField::applyFunc(const char *func, int sizeCThis, const MEDCalculatorDBRangeSelection& thisC)
282 {
283   std::vector<int> tIds=thisC.getIds(sizeCThis);
284   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
285   f1->applyFunc(func);
286   _field->setSelectedComponents(f1,tIds);
287 }
288
289 bool MEDCalculatorDBSliceField::isEqual(const MEDCalculatorDBSliceField* other, const DataArrayInt *cc, const DataArrayInt *nc,
290                                      int sizeCThis, const MEDCalculatorDBRangeSelection& thisC,
291                                      int sizeCOther, const MEDCalculatorDBRangeSelection& otherC, double prec) const
292 {
293   if(cc!=0 || nc!=0)
294     throw INTERP_KERNEL::Exception("Slice::isEqual : not implemented yet node/cell permutation !");
295   std::vector<int> tIds=thisC.getIds(sizeCThis);
296   std::vector<int> oIds=otherC.getIds(sizeCOther);
297   MCAuto<MEDCouplingFieldDouble> f1=_field->keepSelectedComponents(tIds);
298   MCAuto<MEDCouplingFieldDouble> f2=other->_field->keepSelectedComponents(oIds);
299   f2->setMesh(f1->getMesh());
300   return f1->isEqualWithoutConsideringStr(f2,0,prec);
301 }