Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.git] / src / MEDMEM_I / MEDMEM_Mesh_i.cxx
1 // Copyright (C) 2007-2012  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.
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 //=============================================================================
24 // File      : MEDMEM_Mesh_i.cxx
25 // Project   : SALOME
26 // Author    : EDF 
27 //=============================================================================
28 //
29 #include "utilities.h"
30 #include "Utils_CorbaException.hxx"
31 #include "Utils_ORB_INIT.hxx"
32 #include "Utils_SINGLETON.hxx"
33
34 #include "MEDMEM_convert.hxx"
35 #include "MEDMEM_Mesh_i.hxx"
36 #include "MEDMEM_Support_i.hxx"
37 #include "MEDMEM_Family_i.hxx"
38 #include "MEDMEM_Group_i.hxx"
39 #include "MEDMEM_FieldTemplate_i.hxx"
40
41 #include "MEDMEM_Mesh.hxx"
42 #include "MEDMEM_Family.hxx"
43 #include "MEDMEM_Group.hxx"
44 #include "MEDMEM_CellModel.hxx"
45
46 #include "SenderFactory.hxx"
47 #include "MultiCommException.hxx"
48
49 #include <vector>
50
51 using namespace MEDMEM;
52
53 //=============================================================================
54 /*!
55  * Default constructor
56  */
57 //=============================================================================
58 MESH_i::MESH_i():GMESH_i()
59 {
60 }
61 //=============================================================================
62 /*!
63  * Destructor
64  */
65 //=============================================================================
66 MESH_i::~MESH_i()
67 {
68 }
69 //=============================================================================
70 /*!
71  * Constructor
72  */
73 //=============================================================================
74 MESH_i::MESH_i(::MESH * const m ) :GMESH_i(m)
75 {
76 }
77 //=============================================================================
78 /*!
79  * Copy Constructor 
80  */
81 //=============================================================================
82 MESH_i::MESH_i( MESH_i & m) :GMESH_i(m._mesh)
83 {
84 }
85 //=============================================================================
86 /*!
87  * CORBA: boolean indicating if connectivity exists
88  */
89 //=============================================================================
90 CORBA::Boolean MESH_i::existConnectivity
91 (SALOME_MED::medConnectivity connectivityType,
92  SALOME_MED::medEntityMesh entity)
93   throw (SALOME::SALOME_Exception)
94 {
95   if (_mesh==NULL)
96     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
97   try
98     {
99       return ((::MESH*)_mesh)->existConnectivity(connectivityType,
100                                                  convertIdlEntToMedEnt(entity));
101     }
102   catch (MEDEXCEPTION &ex)
103     {
104       MESSAGE("Unable to acces mesh flag existConnectivity");
105       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
106     }
107 }
108
109 //=============================================================================
110 /*!
111  * CORBA: Accessor for a specific coordinate
112  */
113 //=============================================================================
114 CORBA::Double MESH_i::getCoordinate(CORBA::Long Number, CORBA::Long Axis)
115   throw (SALOME::SALOME_Exception)
116 {
117   if (_mesh==NULL)
118     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
119   try
120     {
121       return ((::MESH*)_mesh)->getCoordinate(Number,Axis);
122     }
123   catch (MEDEXCEPTION &ex)
124     {
125       MESSAGE("Unable to acces this coordinate");
126       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
127     }
128 }
129 //=============================================================================
130 /*!
131  * CORBA: Accessor for Coordinates
132  */
133 //=============================================================================
134 SALOME_TYPES::ListOfDouble * MESH_i::getCoordinates(SALOME_MED::medModeSwitch typeSwitch)
135   throw (SALOME::SALOME_Exception)
136 {
137   if (_mesh==NULL)
138     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
139   SALOME_TYPES::ListOfDouble_var myseq = new SALOME_TYPES::ListOfDouble;
140   try
141     {
142       int spaceDimension=((::MESH*)_mesh)->getSpaceDimension();
143       int nbNodes=((::MESH*)_mesh)->getNumberOfNodes();
144       const double * coordinates =((::MESH*)_mesh)->getCoordinates(
145                                                                    convertIdlModeToMedMode(typeSwitch));
146
147       myseq->length(nbNodes*spaceDimension);
148       for (int i=0; i<nbNodes*spaceDimension; i++)
149         {
150           myseq[i]=coordinates[i];
151         };
152     }
153   catch (MEDEXCEPTION &ex)
154     {
155       MESSAGE("Unable to acces the coordinates");
156       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
157     }
158   return myseq._retn();
159 }
160 //=============================================================================
161 /*!
162  * CORBA: 2nd Accessor for Coordinates
163  */
164 //=============================================================================
165 SALOME::SenderDouble_ptr MESH_i::getSenderForCoordinates(SALOME_MED::medModeSwitch typeSwitch)
166   throw (SALOME::SALOME_Exception)
167 {
168   if (_mesh==NULL)
169     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",SALOME::INTERNAL_ERROR);
170   SALOME::SenderDouble_ptr ret;
171   try
172     {
173       int spaceDimension=((::MESH*)_mesh)->getSpaceDimension();
174       int nbNodes=((::MESH*)_mesh)->getNumberOfNodes();
175       const double * coordinates =((::MESH*)_mesh)->getCoordinates(convertIdlModeToMedMode(typeSwitch));
176       ret=SenderFactory::buildSender(*this,coordinates,nbNodes*spaceDimension);
177     }
178   catch (MEDEXCEPTION &ex)
179     {
180       MESSAGE("Unable to acces the coordinates");
181       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
182     }
183   catch(MultiCommException &ex2)
184     THROW_SALOME_CORBA_EXCEPTION(ex2.what(),SALOME::INTERNAL_ERROR);
185   return ret;
186 }
187 //=============================================================================
188 /*!
189  * CORBA: Accessor for connectivities
190  */
191 //=============================================================================
192 SALOME_TYPES::ListOfLong *  MESH_i::getConnectivity(SALOME_MED::medConnectivity mode, 
193                                                     SALOME_MED::medEntityMesh entity, 
194                                                     SALOME_MED::medGeometryElement geomElement)
195   throw (SALOME::SALOME_Exception)
196 {
197   if (_mesh==NULL)
198     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
199   if (verifieParam(entity,geomElement)==false)
200     THROW_SALOME_CORBA_EXCEPTION("parameters don't match", SALOME::BAD_PARAM);
201   SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong;
202   try
203     {
204       int nbelements; 
205       int elt1 = ((::MESH*)_mesh)->getNumberOfElements(
206                                                        convertIdlEntToMedEnt(entity),
207                                                        convertIdlEltToMedElt(geomElement));
208       SCRUTE(elt1);
209       if ( mode == SALOME_MED::MED_DESCENDING)
210         {
211           MESSAGE("MED_DESCENDING");
212           int elt2 =(((::MESH*)_mesh)->getCellsTypes(MED_CELL))->getNumberOfConstituents(1);
213           nbelements= elt2 * elt1;
214           SCRUTE(elt2);
215         }
216       else
217         {
218           MESSAGE("MED_NODAL");
219           nbelements = ((::MESH*)_mesh)->getConnectivityLength
220             (convertIdlConnToMedConn(mode),
221              convertIdlEntToMedEnt(entity),
222              convertIdlEltToMedElt(geomElement));
223         }
224       SCRUTE(entity);
225       SCRUTE(geomElement);
226       SCRUTE(nbelements);
227       myseq->length(nbelements);
228       const int * numbers=((::MESH*)_mesh)->getConnectivity(convertIdlConnToMedConn(mode),
229                                                             convertIdlEntToMedEnt(entity),
230                                                             convertIdlEltToMedElt(geomElement));
231       for (int i=0;i<nbelements;i++)
232         {
233           myseq[i]=numbers[i];
234         }
235     }
236   catch (MEDEXCEPTION &ex)
237     {
238       MESSAGE("Unable to acces connectivities");
239       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
240     }
241   return myseq._retn();
242 }
243 //=============================================================================
244 /*!
245  * CORBA: 2nd Accessor for connectivities
246  */
247 //=============================================================================
248 SALOME::SenderInt_ptr MESH_i::getSenderForConnectivity(SALOME_MED::medConnectivity mode, 
249                                                        SALOME_MED::medEntityMesh entity, 
250                                                        SALOME_MED::medGeometryElement geomElement)
251   throw (SALOME::SALOME_Exception)
252 {
253   if (_mesh==NULL)
254     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
255   if (verifieParam(entity,geomElement)==false)
256     THROW_SALOME_CORBA_EXCEPTION("parameters don't match", SALOME::BAD_PARAM);
257   SALOME::SenderInt_ptr ret;
258   try
259     {
260       int nbelements=((::MESH*)_mesh)->getConnectivityLength(convertIdlConnToMedConn(mode),
261                                                              convertIdlEntToMedEnt(entity),
262                                                              convertIdlEltToMedElt(geomElement));
263       const int * numbers=((::MESH*)_mesh)->getConnectivity(convertIdlConnToMedConn(mode),
264                                                             convertIdlEntToMedEnt(entity),
265                                                             convertIdlEltToMedElt(geomElement));
266       ret=SenderFactory::buildSender(*this,numbers,nbelements);
267     }
268   catch (MEDEXCEPTION &ex)
269     {
270       MESSAGE("Unable to acces connectivities");
271       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
272     }
273   catch(MultiCommException &ex2)
274     THROW_SALOME_CORBA_EXCEPTION(ex2.what(),SALOME::INTERNAL_ERROR);
275   return ret;
276 }
277
278 //=============================================================================
279 /*!
280  * CORBA: Accessor for connectivities
281  */
282 //=============================================================================
283 SALOME_TYPES::ListOfLong* MESH_i::getConnectivityIndex(SALOME_MED::medConnectivity mode, 
284                                                        SALOME_MED::medEntityMesh entity) 
285   throw (SALOME::SALOME_Exception)
286 {
287   if (_mesh==NULL)
288     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
289   SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong;
290   try
291     {
292       int nbelements = ((::MESH*)_mesh)->getNumberOfElements(
293                                                              convertIdlEntToMedEnt(entity),
294                                                              MED_ALL_ELEMENTS) + 1;
295       myseq->length(nbelements);
296       const int * numbers=((::MESH*)_mesh)->getConnectivityIndex(convertIdlConnToMedConn(mode),
297                                                                  convertIdlEntToMedEnt(entity));
298       for (int i=0;i<nbelements;i++)
299         {
300           myseq[i]=numbers[i];
301         }
302     }
303   catch (MEDEXCEPTION &ex)
304     {
305       MESSAGE("Unable to acces connectivities index");
306       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
307     }
308   return myseq._retn();
309 }
310 //=============================================================================
311 /*!
312  * CORBA: Accessor for connectivity index
313  */
314 //=============================================================================
315 SALOME::SenderInt_ptr MESH_i::getSenderForConnectivityIndex(SALOME_MED::medConnectivity mode,
316                                                             SALOME_MED::medEntityMesh entity,
317                                                             SALOME_MED::medGeometryElement geomElement)
318   throw (SALOME::SALOME_Exception)
319 {
320   if (_mesh==NULL)
321     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
322   SALOME::SenderInt_ptr ret;
323   try
324     {
325       int nbelements=((::MESH*)_mesh)->getNumberOfElements( convertIdlEntToMedEnt(entity),
326                                                             convertIdlEltToMedElt(geomElement)) + 1;
327       int iType = 0, nbTypes = ((::MESH*)_mesh)->getNumberOfTypes(convertIdlEntToMedEnt(entity));
328       const MED_EN::medGeometryElement * types = ((::MESH*)_mesh)->getTypes(convertIdlEntToMedEnt(entity));
329       while ( iType < nbTypes && types[iType] != convertIdlEltToMedElt(geomElement))
330         ++iType;
331       int prev_nbelements = ((::MESH*)_mesh)->getGlobalNumberingIndex( convertIdlEntToMedEnt(entity))[iType]-1;
332
333       const int * numbers=((::MESH*)_mesh)->getConnectivityIndex(convertIdlConnToMedConn(mode),
334                                                                  convertIdlEntToMedEnt(entity)) + prev_nbelements;
335       ret=SenderFactory::buildSender(*this,numbers,nbelements);
336     }
337   catch (MEDEXCEPTION &ex)
338     {
339       MESSAGE("Unable to acces connectivities");
340       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
341     }
342   catch(MultiCommException &ex2)
343     THROW_SALOME_CORBA_EXCEPTION(ex2.what(),SALOME::INTERNAL_ERROR);
344   return ret;
345 }
346
347 //=============================================================================
348 /*!
349  * CORBA: Accessor for connectivities
350  */
351 //=============================================================================
352 SALOME_TYPES::ListOfLong* MESH_i::getGlobalNumberingIndex( SALOME_MED::medEntityMesh entity)
353   throw (SALOME::SALOME_Exception)
354 {
355   if (_mesh==NULL)
356     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
357   SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong;
358   try
359     {
360       int nbelements = ((::MESH*)_mesh)->getNumberOfTypes( convertIdlEntToMedEnt(entity)) + 1;
361       myseq->length(nbelements);
362       const int * numbers=((::MESH*)_mesh)->getGlobalNumberingIndex( convertIdlEntToMedEnt(entity));
363       for (int i=0;i<nbelements;i++)
364         {
365           myseq[i]=numbers[i];
366         }
367     }
368   catch (MEDEXCEPTION &ex)
369     {
370       MESSAGE("Unable to acces global index");
371       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
372     }
373   return myseq._retn();
374 }
375
376 //=============================================================================
377 /*!
378  * CORBA: get global element number in connectivity array
379  * not implemented for MED_NODE and MED_ALL_ENTITIES,
380  * MED_NONE and MED_ALL_ELEMENTS.
381  */
382 //=============================================================================
383 CORBA::Long MESH_i::getElementNumber(SALOME_MED::medConnectivity mode,
384                                      SALOME_MED::medEntityMesh entity,
385                                      SALOME_MED::medGeometryElement type,
386                                      const SALOME_TYPES::ListOfLong& connectivity)
387   throw (SALOME::SALOME_Exception)
388 {
389   if (_mesh==NULL)
390     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
391   int numberOfValue = connectivity.length() ;
392   int * myConnectivity = new int[numberOfValue] ;
393   for (int i=0; i<numberOfValue; i++)
394     myConnectivity[i]=connectivity[i] ;
395
396   int result ;
397   try
398     {
399       result = ((::MESH*)_mesh)->getElementNumber(convertIdlConnToMedConn(mode),
400                                                   convertIdlEntToMedEnt(entity),
401                                                   convertIdlEltToMedElt(type),
402                                                   myConnectivity) ;
403     }
404   catch (MEDEXCEPTION &ex) 
405     {
406       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
407     }
408   return result ;
409 }
410 //=============================================================================
411 /*!
412  * CORBA: Accessor for Ascendant connectivities
413  * not implemented for MED_ALL_ENTITIES and MED_MAILLE
414  */
415 //=============================================================================
416 SALOME_TYPES::ListOfLong* MESH_i::getReverseConnectivity(SALOME_MED::medConnectivity mode)
417   throw (SALOME::SALOME_Exception)
418 {
419   if (_mesh==NULL)
420     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
421   SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong;
422   try
423     {
424       int nbelements=((::MESH*)_mesh)->getReverseConnectivityLength(convertIdlConnToMedConn(mode));
425       SCRUTE(nbelements);
426       myseq->length(nbelements);
427       const int * numbers=((::MESH*)_mesh)->getReverseConnectivity(convertIdlConnToMedConn(mode));
428       for (int i=0;i<nbelements;i++)
429         {
430           myseq[i]=numbers[i];
431         }
432     }
433   catch (MEDEXCEPTION &ex)
434     {
435       MESSAGE("Unable to acces reverse connectivities");
436       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
437     }
438   return myseq._retn();
439 }
440 //=============================================================================
441 /*!
442  * CORBA: Accessor for connectivities
443  */
444 //=============================================================================
445 SALOME_TYPES::ListOfLong* MESH_i::getReverseConnectivityIndex(SALOME_MED::medConnectivity mode)
446   throw (SALOME::SALOME_Exception)
447 {
448   if (_mesh==NULL)
449     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
450   SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong;
451   try
452     {
453       int nbelements=((::MESH*)_mesh)->getReverseConnectivityIndexLength(convertIdlConnToMedConn(mode));
454       myseq->length(nbelements);
455       const int * numbers=((::MESH*)_mesh)->getReverseConnectivityIndex(convertIdlConnToMedConn(mode));
456       for (int i=0;i<nbelements;i++)
457         {
458           myseq[i]=numbers[i];
459         }
460     }
461   catch (MEDEXCEPTION &ex)
462     {
463       MESSAGE("Unable to acces reverse connectivities index");
464       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
465     }
466   return myseq._retn();
467 }
468 //=============================================================================
469 /*!
470  * CORBA: Returns connectivity global informations
471  */
472 //=============================================================================
473 SALOME_MED::MESH::connectivityInfos * MESH_i::getConnectGlobal (SALOME_MED::medEntityMesh entity)
474   throw (SALOME::SALOME_Exception)
475 {
476   if (_mesh==NULL)
477     THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR);
478   SALOME_MED::MESH::connectivityInfos_var all=new SALOME_MED::MESH::connectivityInfos;
479   try
480     {
481       MED_EN::medEntityMesh anEntity = convertIdlEntToMedEnt(entity);
482       all->numberOfNodes  = ((::MESH*)_mesh)->getNumberOfNodes();
483
484       int nbTypes=((::MESH*)_mesh)->getNumberOfTypes(anEntity);
485       const medGeometryElement * types =((::MESH*)_mesh)->getTypes(anEntity);
486       all->meshTypes.length(nbTypes);
487       all->numberOfElements.length(nbTypes);
488       all->nodalConnectivityLength.length(nbTypes);
489       all->entityDimension=((::MESH*)_mesh)->getConnectivityptr()->getEntityDimension();
490       for (int i=0; i<nbTypes; i++)
491         {
492           all->meshTypes[i]=convertMedEltToIdlElt(types[i]);
493           all->numberOfElements[i]=((::MESH*)_mesh)->getNumberOfElements(anEntity,types[i]);
494           all->nodalConnectivityLength[i]=
495             ((::MESH*)_mesh)->getConnectivityLength(MED_EN::MED_NODAL,anEntity,types[i]);
496         }
497     }
498   catch (MEDEXCEPTION &ex)
499     {
500       MESSAGE("Unable to acces connectivities informations");
501       THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
502     }
503   return all._retn();
504 }