Salome HOME
Update copyrights
[modules/smesh.git] / src / MEDWrapper / MED_Algorithm.cxx
1 // Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "MED_Algorithm.hxx"
24 #include "MED_Wrapper.hxx"
25 #include "MED_Utilities.hxx"
26
27 #ifdef _DEBUG_
28 static int MYDEBUG = 0;
29 static int MYVALUEDEBUG = 0;
30 #else
31 static int MYDEBUG = 0;
32 static int MYVALUEDEBUG = 0;
33 #endif
34
35 namespace MED
36 {
37   //---------------------------------------------------------------
38   TEntity2TGeom2ElemInfo
39   GetEntity2TGeom2ElemInfo(const PWrapper& theWrapper,
40                            const PMeshInfo& theMeshInfo,
41                            const MED::TEntityInfo& theEntityInfo)
42   {
43     MSG(MYDEBUG,"GetElemsByEntity(...)");
44     TEntity2TGeom2ElemInfo anEntity2TGeom2ElemInfo;
45     MED::TEntityInfo::const_iterator anIter = theEntityInfo.begin();
46     PElemInfo anElemInfo;
47     TErr anErr;
48     for(; anIter != theEntityInfo.end(); anIter++){
49       const EEntiteMaillage& anEntity = anIter->first;
50       const TGeom2Size& aGeom2Size = anIter->second;
51       TGeom2ElemInfo& aGeom2ElemInfo = anEntity2TGeom2ElemInfo[anEntity];
52
53       if(anEntity == eNOEUD){
54         aGeom2ElemInfo[ePOINT1] = theWrapper->GetPElemInfo(theMeshInfo);
55         continue;
56       }
57
58       TGeom2Size::const_iterator anIter2 = aGeom2Size.begin();
59       for(; anIter2 != aGeom2Size.end(); anIter2++){
60         const EGeometrieElement& aGeom = anIter2->first;
61         aGeom2ElemInfo[aGeom] = theWrapper->GetPElemInfo(theMeshInfo,anEntity,aGeom,MED::eNOD,&anErr);
62       }
63     }
64     ADDMSG(MYDEBUG,"\n");
65     return anEntity2TGeom2ElemInfo;
66   }
67
68   //---------------------------------------------------------------
69   TFamilyInfoSet
70   GetFamilyInfoSet(const PWrapper& theWrapper,
71                    const PMeshInfo& theMeshInfo)
72   {
73     MSG(MYDEBUG,"GetFamilies(...)");
74     TErr anErr;
75     TFamilyInfoSet aFamilyInfoSet;
76     TInt aNbFam = theWrapper->GetNbFamilies(*theMeshInfo);
77     INITMSG(MYDEBUG,"GetNbFamilies() = "<<aNbFam<<"\n");
78     for(TInt iFam = 1; iFam <= aNbFam; iFam++){
79       PFamilyInfo aFamilyInfo = theWrapper->GetPFamilyInfo(theMeshInfo,iFam,&anErr);
80       if(anErr >= 0)
81         aFamilyInfoSet.insert(aFamilyInfo);
82     }
83     ADDMSG(MYDEBUG,"\n");
84     return aFamilyInfoSet;
85   }
86
87   //---------------------------------------------------------------
88   TGroupInfo
89   GetGroupInfo(const TFamilyInfoSet& theFamilyInfoSet)
90   {
91     MSG(MYDEBUG,"GetFamiliesByGroup(...)");
92     TGroupInfo aGroup;
93     TFamilyInfoSet::const_iterator anIter = theFamilyInfoSet.begin();
94     for(; anIter != theFamilyInfoSet.end(); anIter++){
95       const PFamilyInfo& aFamilyInfo = *anIter;
96       TInt aNbGroup = aFamilyInfo->GetNbGroup();
97       for(TInt iGroup = 0; iGroup < aNbGroup; iGroup++){
98         aGroup[aFamilyInfo->GetGroupName(iGroup)].insert(aFamilyInfo);
99       }
100     }
101
102 #ifdef _DEBUG_
103     if(MYDEBUG){
104       TGroupInfo::const_iterator anIter = aGroup.begin();
105       for(; anIter != aGroup.end(); anIter++){
106         const std::string& aName = anIter->first;
107         INITMSG(MYDEBUG,"aGroupName = '"<<aName<<"'\n");
108         const TFamilyInfoSet& aFamilyInfoSet = anIter->second;
109         TFamilyInfoSet::const_iterator anFamIter = aFamilyInfoSet.begin();
110         for(; anFamIter != aFamilyInfoSet.end(); anFamIter++){
111           const PFamilyInfo& aFamilyInfo = *anFamIter;
112           INITMSG(MYDEBUG,"aFamilyName = '"<<aFamilyInfo->GetName()<<"'\n");
113         }
114       }
115       ADDMSG(MYDEBUG,"\n");
116     }
117 #endif
118
119     return aGroup;
120   }
121
122   //---------------------------------------------------------------
123   TFieldInfo2TimeStampInfoSet
124   GetFieldInfo2TimeStampInfoSet(const PWrapper& theWrapper,
125                                 const PMeshInfo& theMeshInfo,
126                                 const MED::TEntityInfo& theEntityInfo)
127   {
128     MSG(MYDEBUG,"GetFieldsByEntity(...)");
129     TFieldInfo2TimeStampInfoSet aFieldInfo2TimeStampInfoSet;
130     TInt aNbFields = theWrapper->GetNbFields();
131     INITMSG(MYDEBUG,"GetNbFields() = "<<aNbFields<<"\n");
132     for(TInt iField = 1; iField <= aNbFields; iField++){
133       PFieldInfo aFieldInfo = theWrapper->GetPFieldInfo(theMeshInfo,iField);
134       INITMSG(MYDEBUG,"aFieldName = '"<<aFieldInfo->GetName()<<
135               "'; aNbComp = "<<aFieldInfo->GetNbComp()<<"; ");
136       TGeom2Size aGeom2Size;
137       EEntiteMaillage anEntity = EEntiteMaillage(-1);
138       TInt aNbTimeStamps = theWrapper->GetNbTimeStamps(aFieldInfo,theEntityInfo,anEntity,aGeom2Size);
139       ADDMSG(MYDEBUG,"anEntity = "<<anEntity<<"; GetNbTimeStamps = "<<aNbTimeStamps<<"\n");
140       for(TInt iTimeStamp = 1; iTimeStamp <= aNbTimeStamps; iTimeStamp++){
141         PTimeStampInfo aTimeStamp =
142           theWrapper->GetPTimeStampInfo(aFieldInfo,anEntity,aGeom2Size,iTimeStamp);
143         aFieldInfo2TimeStampInfoSet[aFieldInfo].insert(aTimeStamp);
144         INITMSG(MYDEBUG,
145                 "aDt = "<<aTimeStamp->GetDt()<<
146                 ", Unit = \'"<<aTimeStamp->GetUnitDt()<<"\n");
147       }
148     }
149     ADDMSG(MYDEBUG,"\n");
150     return aFieldInfo2TimeStampInfoSet;
151   }
152
153   //---------------------------------------------------------------
154   TEntite2TFieldInfo2TimeStampInfoSet
155   GetEntite2TFieldInfo2TimeStampInfoSet(const TFieldInfo2TimeStampInfoSet& theFieldInfo2TimeStampInfoSet)
156   {
157     TEntite2TFieldInfo2TimeStampInfoSet anEntite2TFieldInfo2TimeStampInfoSet;
158     TFieldInfo2TimeStampInfoSet::const_iterator anIter = theFieldInfo2TimeStampInfoSet.begin();
159     for(; anIter != theFieldInfo2TimeStampInfoSet.end(); anIter++){
160       const TTimeStampInfoSet& aTimeStampInfoSet = anIter->second;
161       //const PFieldInfo& aFieldInfo = anIter->first;
162       if(aTimeStampInfoSet.empty())
163         continue;
164       const PTimeStampInfo& aTimeStampInfo = *aTimeStampInfoSet.begin();
165       anEntite2TFieldInfo2TimeStampInfoSet[ConvertEntity(aTimeStampInfo->GetEntity())].insert(*anIter);
166     }
167     return anEntite2TFieldInfo2TimeStampInfoSet;
168   }
169
170   //---------------------------------------------------------------
171   bool
172   operator<(const TFamilyTSize& theLeft, const TFamilyTSize& theRight)
173   {
174     const MED::PFamilyInfo& aLeftInfo = boost::get<0>(theLeft);
175     const MED::PFamilyInfo& aRightInfo = boost::get<0>(theRight);
176     return aLeftInfo->GetId() < aRightInfo->GetId();
177   }
178
179   //---------------------------------------------------------------
180   TEntity2FamilySet
181   GetEntity2FamilySet(const PWrapper& theWrapper,
182                       const TEntity2TGeom2ElemInfo& theEntity2TGeom2ElemInfo,
183                       const TFamilyInfoSet& theFamilyInfoSet)
184   {
185     MSG(MYDEBUG,"GetFamiliesByEntity(...)");
186     TEntity2FamilySet anEntity2FamilySet;
187
188     typedef std::map<TInt,PFamilyInfo> TId2Family;
189     TId2Family anId2Family;
190     TFamilyInfoSet::const_iterator anIter = theFamilyInfoSet.begin();
191     for(; anIter != theFamilyInfoSet.end(); anIter++){
192       const PFamilyInfo& aFamilyInfo = *anIter;
193       anId2Family.insert(TId2Family::value_type(aFamilyInfo->GetId(),aFamilyInfo));
194     }
195
196     if(!anId2Family.empty()){
197       typedef std::map<TInt,TInt> TFamilyID2Size;
198       typedef std::map<EEntiteMaillage,TFamilyID2Size> TEntity2FamilyID;
199       TEntity2FamilyID anEntity2FamilyID;
200
201       if(!theEntity2TGeom2ElemInfo.empty()){
202         TEntity2TGeom2ElemInfo::const_iterator anIter = theEntity2TGeom2ElemInfo.begin();
203         for(; anIter != theEntity2TGeom2ElemInfo.end(); anIter++){
204           const EEntiteMaillage& anEntity = anIter->first;
205           TFamilyID2Size& aFamilyID2Size = anEntity2FamilyID[anEntity];
206           const TGeom2ElemInfo& aGeom2ElemInfo = anIter->second;
207           TGeom2ElemInfo::const_iterator aGeom2ElemInfoIter = aGeom2ElemInfo.begin();
208           for(; aGeom2ElemInfoIter != aGeom2ElemInfo.end(); aGeom2ElemInfoIter++){
209             const PElemInfo& aElemInfo = aGeom2ElemInfoIter->second;
210             if(TInt aNbElem = aElemInfo->GetNbElem()){
211               for(TInt i = 0; i < aNbElem; i++){
212                 aFamilyID2Size[aElemInfo->GetFamNum(i)] += 1;
213               }
214             }
215           }
216         }
217       }
218
219       if(!anEntity2FamilyID.empty()){
220         TEntity2FamilyID::const_iterator anIter = anEntity2FamilyID.begin();
221         for(; anIter != anEntity2FamilyID.end(); anIter++){
222           const EEntiteMaillage& anEntity = anIter->first;
223           INITMSG(MYDEBUG,"anEntity = "<<anEntity<<":\n");
224           const TFamilyID2Size& aFamilyID2Size = anIter->second;
225           TFamilyID2Size::const_iterator anIter2 = aFamilyID2Size.begin();
226           for(; anIter2 != aFamilyID2Size.end(); anIter2++){
227             TInt anId = anIter2->first;
228             TInt aSize = anIter2->second;
229             TId2Family::const_iterator anIter3 = anId2Family.find(anId);
230             if(anIter3 != anId2Family.end()){
231               const PFamilyInfo& aFamilyInfo = anIter3->second;
232               anEntity2FamilySet[anEntity].insert(TFamilyTSize(aFamilyInfo,aSize));
233               INITMSG(MYDEBUG,
234                       "aFamilyName = '"<<aFamilyInfo->GetName()<<
235                       "' anId = "<<aFamilyInfo->GetId()<<"\n");
236             }
237           }
238         }
239       }
240     }
241     ADDMSG(MYDEBUG,"\n");
242     return anEntity2FamilySet;
243   }
244
245   //---------------------------------------------------------------
246   TKey2Gauss
247   GetKey2Gauss(const PWrapper& theWrapper,
248                TErr* theErr,
249                EModeSwitch theMode)
250   {
251     INITMSG(MYDEBUG,"GetKey2Gauss - theMode = "<<theMode<<std::endl);
252     TKey2Gauss aKey2Gauss;
253     TInt aNbGauss = theWrapper->GetNbGauss(theErr);
254     for(TInt anId = 1; anId <= aNbGauss; anId++){
255       TGaussInfo::TInfo aPreInfo = theWrapper->GetGaussPreInfo(anId);
256       PGaussInfo anInfo = theWrapper->CrGaussInfo(aPreInfo,theMode);
257       theWrapper->GetGaussInfo(anId,anInfo,theErr);
258       TGaussInfo::TKey aKey = boost::get<0>(aPreInfo);
259       aKey2Gauss[aKey] = anInfo;
260
261 #ifdef _DEBUG_
262       const EGeometrieElement& aGeom = boost::get<0>(aKey);
263       const std::string& aName = boost::get<1>(aKey);
264       INITMSG(MYDEBUG,
265               "- aGeom = "<<aGeom<<
266               "; aName = '"<<aName<<"'"<<
267               std::endl);
268 #endif
269
270     }
271     return aKey2Gauss;
272   }
273
274   //---------------------------------------------------------------
275   PProfileInfo
276   GetProfileInfo(const PWrapper& theWrapper,
277                  const std::string& theProfileName,
278                  TErr* theErr,
279                  EModeProfil theMode)
280   {
281     PProfileInfo anInfo;
282     TInt aNbProfiles = theWrapper->GetNbProfiles(theErr);
283     for(TInt anId = 1; anId <= aNbProfiles; anId++){
284       TProfileInfo::TInfo aPreInfo = theWrapper->GetProfilePreInfo(anId);
285       const std::string& aName = boost::get<0>(aPreInfo);
286       if(aName == theProfileName)
287         return theWrapper->GetPProfileInfo(anId,theMode,theErr);
288     }
289     return anInfo;
290   }
291
292   //---------------------------------------------------------------
293   TMKey2Profile
294   GetMKey2Profile(const PWrapper& theWrapper,
295                   TErr* theErr,
296                   EModeProfil theMode)
297   {
298     INITMSG(MYDEBUG,"GetMKey2Profile - theMode = "<<theMode<<std::endl);
299     TKey2Profile aKey2Profile;
300     TInt aNbProfiles = theWrapper->GetNbProfiles(theErr);
301     for(TInt anId = 1; anId <= aNbProfiles; anId++){
302       TProfileInfo::TInfo aPreInfo = theWrapper->GetProfilePreInfo(anId);
303       PProfileInfo anInfo = theWrapper->GetPProfileInfo(anId,theMode,theErr);
304       const std::string& aName = boost::get<0>(aPreInfo);
305       aKey2Profile[aName] = anInfo;
306
307 #ifdef _DEBUG_
308       INITMSG(MYDEBUG,
309               "- aName = '"<<aName<<"'"<<
310               " : "<<
311               std::endl);
312       TInt aNbElem = anInfo->GetSize();
313       for(TInt iElem = 0; iElem < aNbElem; iElem++){
314         ADDMSG(MYVALUEDEBUG,anInfo->GetElemNum(iElem)<<", ");
315       }
316       ADDMSG(MYVALUEDEBUG, std::endl);
317 #endif
318
319     }
320     return TMKey2Profile(theMode,aKey2Profile);
321   }
322
323   //---------------------------------------------------------------
324   EEntiteMaillage
325   GetEntityByFamilyId(PGrilleInfo& theInfo,
326                       TInt theId)
327   {
328     TElemNum::iterator aNodeFamIter = (theInfo->myFamNumNode).begin();
329     for(;aNodeFamIter != (theInfo->myFamNumNode).end(); aNodeFamIter++){
330       if(theId == *aNodeFamIter)
331         return eNOEUD;
332     }
333     TElemNum::iterator aCellFamIter = (theInfo->myFamNum).begin();
334     for(;aCellFamIter != (theInfo->myFamNum).end(); aCellFamIter++){
335       if(theId == *aCellFamIter)
336         return eMAILLE;
337     }
338     EXCEPTION(std::runtime_error, "GetEntityByFamilyId - fails");
339     return EEntiteMaillage(-1);
340   }
341
342   //---------------------------------------------------------------
343   TFamilyID2NbCells
344   GetFamilyID2NbCells(PGrilleInfo& theInfo)
345   {
346     TFamilyID2NbCells aFamily2NbCells;
347     TInt aNbNodes = theInfo->myFamNumNode.size();
348     TInt aNbCells = theInfo->myFamNum.size();
349     for(TInt i=0; i<aNbNodes; i++) aFamily2NbCells[theInfo->GetFamNumNode(i)] = 0;
350     for(TInt i=0; i<aNbCells; i++) aFamily2NbCells[theInfo->GetFamNum(i)] = 0;
351     for(TInt i=0; i<aNbNodes; i++) aFamily2NbCells[theInfo->GetFamNumNode(i)] += 1;
352     for(TInt i=0; i<aNbCells; i++) aFamily2NbCells[theInfo->GetFamNum(i)] += 1;
353     return aFamily2NbCells;
354   }
355
356   //---------------------------------------------------------------
357   EEntiteMaillage
358   ConvertEntity(const EEntiteMaillage& aEntity)
359   {
360     switch( aEntity ){
361     case eNOEUD_ELEMENT:
362     case eMAILLE:
363       return eMAILLE; // eNOEUD_ELEMENT is eMAILLE
364     case eFACE:
365     case eARETE:
366     case eNOEUD:
367       return aEntity;
368     default:
369       break;
370     }
371     return EEntiteMaillage(-1);
372   }
373 }