Back to index

salome-smesh  6.5.0
DriverUNV_R_SMDS_Mesh.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include "DriverUNV_R_SMDS_Mesh.h"
00024 #include "SMDS_Mesh.hxx"
00025 #include "SMDS_MeshGroup.hxx"
00026 
00027 #include "utilities.h"
00028 
00029 #include "UNV164_Structure.hxx"
00030 #include "UNV2411_Structure.hxx"
00031 #include "UNV2412_Structure.hxx"
00032 #include "UNV2417_Structure.hxx"
00033 #include "UNV2420_Structure.hxx"
00034 #include "UNV_Utilities.hxx"
00035 
00036 #include <Basics_Utils.hxx>
00037 
00038 using namespace std;
00039 
00040 
00041 #ifdef _DEBUG_
00042 static int MYDEBUG = 1;
00043 #else
00044 static int MYDEBUG = 0;
00045 #endif
00046 
00047 namespace
00048 {
00052   void transformNodes( UNV2411::TDataSet::const_iterator fromNode,
00053                        UNV2411::TDataSet::const_iterator endNode,
00054                        const UNV2420::TRecord &          csRecord )
00055   {
00056     const int csLabel = fromNode->exp_coord_sys_num;
00057 
00058     UNV2411::TDataSet::const_iterator nodeIt;
00059 
00060     // apply Transformation Matrix
00061     if ( !csRecord.isIdentityMatrix() )
00062     {
00063       for ( nodeIt = fromNode; nodeIt != endNode; ++nodeIt )
00064       {
00065         const UNV2411::TRecord& nodeRec = *nodeIt;
00066         if ( nodeRec.exp_coord_sys_num == csLabel )
00067           csRecord.ApplyMatrix( (double*) nodeRec.coord );
00068       }
00069     }
00070 
00071     // transform from Cylindrical CS
00072     if ( csRecord.coord_sys_type == UNV2420::Cylindrical )
00073     {
00074       for ( nodeIt = fromNode; nodeIt != endNode; ++nodeIt )
00075       {
00076         const UNV2411::TRecord& nodeRec = *nodeIt;
00077         if ( nodeRec.exp_coord_sys_num == csLabel )
00078           csRecord.FromCylindricalCS( (double*) nodeRec.coord );
00079       }
00080     }
00081     // transform from Spherical CS
00082     else if ( csRecord.coord_sys_type == UNV2420::Spherical )
00083     {
00084       for ( nodeIt = fromNode; nodeIt != endNode; ++nodeIt )
00085       {
00086         const UNV2411::TRecord& nodeRec = *nodeIt;
00087         if ( nodeRec.exp_coord_sys_num == csLabel )
00088           csRecord.FromSphericalCS( (double*) nodeRec.coord );
00089       }
00090     }
00091   }
00092 }
00093 
00094 DriverUNV_R_SMDS_Mesh::~DriverUNV_R_SMDS_Mesh()
00095 {
00096   if (myGroup != 0) 
00097     delete myGroup;
00098 }
00099 
00100 
00101 Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
00102 {
00103   Kernel_Utils::Localizer loc;
00104   Status aResult = DRS_OK;
00105   std::ifstream in_stream(myFile.c_str());
00106   try
00107   {
00108     {
00109       // Read Units
00110       UNV164::TRecord aUnitsRecord;
00111       UNV164::Read( in_stream, aUnitsRecord );
00112 
00113       // Read Coordinate systems
00114       UNV2420::TDataSet aCoordSysDataSet;
00115       UNV2420::Read(in_stream, myMeshName, aCoordSysDataSet);
00116 
00117       // Read nodes
00118       using namespace UNV2411;
00119       TDataSet aDataSet2411;
00120       UNV2411::Read(in_stream,aDataSet2411);
00121       if(MYDEBUG) MESSAGE("Perform - aDataSet2411.size() = "<<aDataSet2411.size());
00122 
00123       // Move nodes in a global CS
00124       if ( !aCoordSysDataSet.empty() )
00125       {
00126         UNV2420::TDataSet::const_iterator csIter = aCoordSysDataSet.begin();
00127         for ( ; csIter != aCoordSysDataSet.end(); ++csIter )
00128         {
00129           // find any node in this CS
00130           TDataSet::const_iterator nodeIter = aDataSet2411.begin();
00131           for (; nodeIter != aDataSet2411.end(); nodeIter++)
00132             if ( nodeIter->exp_coord_sys_num == csIter->coord_sys_label )
00133             {
00134               transformNodes( nodeIter, aDataSet2411.end(), *csIter );
00135               break;
00136             }
00137         }
00138       }
00139       // Move nodes to SI unit system
00140       const double lenFactor = aUnitsRecord.factors[ UNV164::LENGTH_FACTOR ]; 
00141       if ( lenFactor != 1. )
00142       {
00143         TDataSet::iterator nodeIter = aDataSet2411.begin(), nodeEnd;
00144         for ( nodeEnd = aDataSet2411.end(); nodeIter != nodeEnd; nodeIter++)
00145         {
00146           UNV2411::TRecord& nodeRec = *nodeIter;
00147           nodeRec.coord[0] *= lenFactor;
00148           nodeRec.coord[1] *= lenFactor;
00149           nodeRec.coord[2] *= lenFactor;
00150         }
00151       }
00152 
00153       // Create nodes in the mesh
00154       TDataSet::const_iterator anIter = aDataSet2411.begin();
00155       for(; anIter != aDataSet2411.end(); anIter++)
00156       {
00157         const TRecord& aRec = *anIter;
00158         myMesh->AddNodeWithID(aRec.coord[0],aRec.coord[1],aRec.coord[2],aRec.label);
00159       }
00160     }
00161     {
00162       using namespace UNV2412;
00163       TDataSet aDataSet2412;
00164       UNV2412::Read(in_stream,aDataSet2412);
00165       TDataSet::const_iterator anIter = aDataSet2412.begin();
00166       if(MYDEBUG) MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
00167       for(; anIter != aDataSet2412.end(); anIter++)
00168       {
00169         SMDS_MeshElement* anElement = NULL;
00170         const TRecord& aRec = *anIter;
00171         if(IsBeam(aRec.fe_descriptor_id)) {
00172           switch ( aRec.node_labels.size() ) {
00173           case 2: // edge with two nodes
00174             //MESSAGE("add edge " << aLabel << " " << aRec.node_labels[0] << " " << aRec.node_labels[1]);
00175             anElement = myMesh->AddEdgeWithID(aRec.node_labels[0],
00176                                               aRec.node_labels[1],
00177                                               aRec.label);
00178             break;
00179           case 3: // quadratic edge (with 3 nodes)
00180             //MESSAGE("add edge " << aRec.label << " " << aRec.node_labels[0] << " " << aRec.node_labels[1] << " " << aRec.node_labels[2]);
00181             anElement = myMesh->AddEdgeWithID(aRec.node_labels[0],
00182                                               aRec.node_labels[2],
00183                                               aRec.node_labels[1],
00184                                               aRec.label);
00185           }
00186         }
00187         else if(IsFace(aRec.fe_descriptor_id)) {
00188           //MESSAGE("add face " << aRec.label);
00189           switch(aRec.fe_descriptor_id){
00190           case 41: // Plane Stress Linear Triangle      
00191           case 51: // Plane Strain Linear Triangle      
00192           case 61: // Plate Linear Triangle             
00193           case 74: // Membrane Linear Triangle          
00194           case 81: // Axisymetric Solid Linear Triangle 
00195           case 91: // Thin Shell Linear Triangle        
00196             anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
00197                                               aRec.node_labels[1],
00198                                               aRec.node_labels[2],
00199                                               aRec.label);
00200             break;
00201             
00202           case 42: //  Plane Stress Parabolic Triangle       
00203           case 52: //  Plane Strain Parabolic Triangle       
00204           case 62: //  Plate Parabolic Triangle              
00205           case 72: //  Membrane Parabolic Triangle           
00206           case 82: //  Axisymetric Solid Parabolic Triangle  
00207           case 92: //  Thin Shell Parabolic Triangle         
00208             //MESSAGE("add face " << aRec.label << " " << aRec.node_labels[0] << " " << aRec.node_labels[1] << " " << aRec.node_labels[2] << " " << aRec.node_labels[3] << " " << aRec.node_labels[4] << " " << aRec.node_labels[5]);
00209             anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
00210                                               aRec.node_labels[2],
00211                                               aRec.node_labels[4],
00212                                               aRec.node_labels[1],
00213                                               aRec.node_labels[3],
00214                                               aRec.node_labels[5],
00215                                               aRec.label);
00216             break;
00217             
00218           case 44: // Plane Stress Linear Quadrilateral     
00219           case 54: // Plane Strain Linear Quadrilateral     
00220           case 64: // Plate Linear Quadrilateral            
00221           case 71: // Membrane Linear Quadrilateral         
00222           case 84: // Axisymetric Solid Linear Quadrilateral
00223           case 94: // Thin Shell Linear Quadrilateral       
00224             anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
00225                                               aRec.node_labels[1],
00226                                               aRec.node_labels[2],
00227                                               aRec.node_labels[3],
00228                                               aRec.label);
00229             break;
00230             
00231           case 45: // Plane Stress Parabolic Quadrilateral      
00232           case 55: // Plane Strain Parabolic Quadrilateral      
00233           case 65: // Plate Parabolic Quadrilateral             
00234           case 75: // Membrane Parabolic Quadrilateral          
00235           case 85: // Axisymetric Solid Parabolic Quadrilateral 
00236           case 95: // Thin Shell Parabolic Quadrilateral        
00237             anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
00238                                               aRec.node_labels[2],
00239                                               aRec.node_labels[4],
00240                                               aRec.node_labels[6],
00241                                               aRec.node_labels[1],
00242                                               aRec.node_labels[3],
00243                                               aRec.node_labels[5],
00244                                               aRec.node_labels[7],
00245                                               aRec.label);
00246             break;
00247           }
00248         }
00249         else if(IsVolume(aRec.fe_descriptor_id)){
00250           //MESSAGE("add volume " << aRec.label);
00251           switch(aRec.fe_descriptor_id){
00252             
00253           case 111: // Solid Linear Tetrahedron - TET4
00254             anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
00255                                                 aRec.node_labels[2],
00256                                                 aRec.node_labels[1],
00257                                                 aRec.node_labels[3],
00258                                                 aRec.label);
00259             break;
00260 
00261           case 118: // Solid Quadratic Tetrahedron - TET10
00262             anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
00263                                                 aRec.node_labels[4],
00264                                                 aRec.node_labels[2],
00265 
00266                                                 aRec.node_labels[9],
00267 
00268                                                 aRec.node_labels[5],
00269                                                 aRec.node_labels[3],
00270                                                 aRec.node_labels[1],
00271 
00272                                                 aRec.node_labels[6],
00273                                                 aRec.node_labels[8],
00274                                                 aRec.node_labels[7],
00275                                                 aRec.label);
00276             break;
00277             
00278           case 112: // Solid Linear Prism - PRISM6
00279             anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
00280                                                 aRec.node_labels[2],
00281                                                 aRec.node_labels[1],
00282                                                 aRec.node_labels[3],
00283                                                 aRec.node_labels[5],
00284                                                 aRec.node_labels[4],
00285                                                 aRec.label);
00286             break;
00287             
00288           case 113: // Solid Quadratic Prism - PRISM15
00289             anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
00290                                                 aRec.node_labels[4],
00291                                                 aRec.node_labels[2],
00292 
00293                                                 aRec.node_labels[9],
00294                                                 aRec.node_labels[13],
00295                                                 aRec.node_labels[11],
00296 
00297                                                 aRec.node_labels[5],
00298                                                 aRec.node_labels[3],
00299                                                 aRec.node_labels[1],
00300 
00301                                                 aRec.node_labels[14],
00302                                                 aRec.node_labels[12],
00303                                                 aRec.node_labels[10],
00304 
00305                                                 aRec.node_labels[6],
00306                                                 aRec.node_labels[8],
00307                                                 aRec.node_labels[7],
00308                                                 aRec.label);
00309             break;
00310             
00311           case 115: // Solid Linear Brick - HEX8
00312             anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
00313                                                 aRec.node_labels[3],
00314                                                 aRec.node_labels[2],
00315                                                 aRec.node_labels[1],
00316                                                 aRec.node_labels[4],
00317                                                 aRec.node_labels[7],
00318                                                 aRec.node_labels[6],
00319                                                 aRec.node_labels[5],
00320                                                 aRec.label);
00321             break;
00322 
00323           case 116: // Solid Quadratic Brick - HEX20
00324             anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
00325                                                 aRec.node_labels[6],
00326                                                 aRec.node_labels[4],
00327                                                 aRec.node_labels[2],
00328 
00329                                                 aRec.node_labels[12],
00330                                                 aRec.node_labels[18],
00331                                                 aRec.node_labels[16],
00332                                                 aRec.node_labels[14],
00333 
00334                                                 aRec.node_labels[7],
00335                                                 aRec.node_labels[5],
00336                                                 aRec.node_labels[3],
00337                                                 aRec.node_labels[1],
00338 
00339                                                 aRec.node_labels[19],
00340                                                 aRec.node_labels[17],
00341                                                 aRec.node_labels[15],
00342                                                 aRec.node_labels[13],
00343 
00344                                                 aRec.node_labels[8],
00345                                                 aRec.node_labels[11],
00346                                                 aRec.node_labels[10],
00347                                                 aRec.node_labels[9],
00348                                                 aRec.label);
00349             break;
00350 
00351           case 114: // pyramid of 13 nodes (quadratic) - PIRA13
00352             anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
00353                                                 aRec.node_labels[6],
00354                                                 aRec.node_labels[4],
00355                                                 aRec.node_labels[2],
00356                                                 aRec.node_labels[7],
00357                                                 aRec.node_labels[5],
00358                                                 aRec.node_labels[3],
00359                                                 aRec.node_labels[1],
00360 
00361                                                 aRec.node_labels[8],
00362                                                 aRec.node_labels[11],
00363                                                 aRec.node_labels[10],
00364                                                 aRec.node_labels[9],
00365                                                 aRec.node_labels[12],
00366                                                 aRec.label);
00367             break;
00368 
00369           }
00370         }
00371         if(!anElement)
00372           MESSAGE("DriverUNV_R_SMDS_Mesh::Perform - can not add element with ID = "<<aRec.label<<" and type = "<<aRec.fe_descriptor_id);
00373       }
00374     }
00375     {
00376       using namespace UNV2417;      
00377       TDataSet aDataSet2417;
00378       UNV2417::Read(in_stream,aDataSet2417);
00379       if(MYDEBUG) MESSAGE("Perform - aDataSet2417.size() = "<<aDataSet2417.size());
00380       if  (aDataSet2417.size() > 0) {
00381         myGroup = new SMDS_MeshGroup(myMesh);
00382         TDataSet::const_iterator anIter = aDataSet2417.begin();
00383         for(; anIter != aDataSet2417.end(); anIter++){
00384           const TGroupId& aLabel = anIter->first;
00385           const TRecord& aRec = anIter->second;
00386 
00387           int aNodesNb = aRec.NodeList.size();
00388           int aElementsNb = aRec.ElementList.size();
00389 
00390           bool useSuffix = ((aNodesNb > 0) && (aElementsNb > 0));
00391           int i;
00392           if (aNodesNb > 0) {
00393             SMDS_MeshGroup* aNodesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Node);
00394             std::string aGrName = (useSuffix) ? aRec.GroupName + "_Nodes" : aRec.GroupName;
00395             int i = aGrName.find( "\r" );
00396             if (i > 0)
00397               aGrName.erase (i, 2);
00398             myGroupNames.insert(TGroupNamesMap::value_type(aNodesGroup, aGrName));
00399             myGroupId.insert(TGroupIdMap::value_type(aNodesGroup, aLabel));
00400 
00401             for (i = 0; i < aNodesNb; i++) {
00402               const SMDS_MeshNode* aNode = myMesh->FindNode(aRec.NodeList[i]);
00403               if (aNode)
00404                 aNodesGroup->Add(aNode);
00405             }
00406           }
00407           if (aElementsNb > 0){
00408             SMDS_MeshGroup* aEdgesGroup = 0;
00409             SMDS_MeshGroup* aFacesGroup = 0;
00410             SMDS_MeshGroup* aVolumeGroup = 0;
00411             bool createdGroup = false;
00412 
00413             for (i = 0; i < aElementsNb; i++) {
00414               const SMDS_MeshElement* aElement = myMesh->FindElement(aRec.ElementList[i]);
00415               if (aElement) {
00416                 switch (aElement->GetType()) {
00417                 case SMDSAbs_Edge:
00418                   if (!aEdgesGroup) {
00419                     aEdgesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Edge);
00420                     if (!useSuffix && createdGroup) useSuffix = true;
00421                     std::string aEdgesGrName = (useSuffix) ? aRec.GroupName + "_Edges" : aRec.GroupName;
00422                     int i = aEdgesGrName.find( "\r" );
00423                     if (i > 0)
00424                       aEdgesGrName.erase (i, 2);
00425                     myGroupNames.insert(TGroupNamesMap::value_type(aEdgesGroup, aEdgesGrName));
00426                     myGroupId.insert(TGroupIdMap::value_type(aEdgesGroup, aLabel));
00427                     createdGroup = true;
00428                   }
00429                   aEdgesGroup->Add(aElement);
00430                   break;
00431                 case SMDSAbs_Face:
00432                   if (!aFacesGroup) {
00433                     aFacesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Face);
00434                     if (!useSuffix && createdGroup) useSuffix = true;
00435                     std::string aFacesGrName = (useSuffix) ? aRec.GroupName + "_Faces" : aRec.GroupName;
00436                     int i = aFacesGrName.find( "\r" );
00437                     if (i > 0)
00438                       aFacesGrName.erase (i, 2);
00439                     myGroupNames.insert(TGroupNamesMap::value_type(aFacesGroup, aFacesGrName));
00440                     myGroupId.insert(TGroupIdMap::value_type(aFacesGroup, aLabel));
00441                     createdGroup = true;
00442                   }
00443                   aFacesGroup->Add(aElement);
00444                   break;
00445                 case SMDSAbs_Volume:
00446                   if (!aVolumeGroup) {
00447                     aVolumeGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Volume);
00448                     if (!useSuffix && createdGroup) useSuffix = true;
00449                     std::string aVolumeGrName = (useSuffix) ? aRec.GroupName + "_Volumes" : aRec.GroupName;
00450                     int i = aVolumeGrName.find( "\r" );
00451                     if (i > 0)
00452                       aVolumeGrName.erase (i, 2);
00453                     myGroupNames.insert(TGroupNamesMap::value_type(aVolumeGroup, aVolumeGrName));
00454                     myGroupId.insert(TGroupIdMap::value_type(aVolumeGroup, aLabel));
00455                     createdGroup = true;
00456                   }
00457                   aVolumeGroup->Add(aElement);
00458                   break;
00459                 }
00460               } 
00461             }
00462           }
00463         }
00464       }
00465     } 
00466   }
00467   catch(const std::exception& exc){
00468     INFOS("Follow exception was cought:\n\t"<<exc.what());
00469   }
00470   catch(...){
00471     INFOS("Unknown exception was cought !!!");
00472   }
00473   if (myMesh)
00474     myMesh->compactMesh();
00475   return aResult;
00476 }