Back to index

salome-med  6.5.0
MEDMEMTest_MeshFuse.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 // File      : MEDMEMTest_MeshFuse.cxx
00023 // Created   : Mon Jul 13 10:35:22 2009
00024 // Author    : Edward AGAPOV (eap)
00025 //
00026 #include "MEDMEMTest.hxx"
00027 #include <cppunit/Message.h>
00028 #include <cppunit/TestAssert.h>
00029 
00030 #include "MEDMEM_Grid.hxx"
00031 #include "MEDMEM_MeshFuse.hxx"
00032 #include "MEDMEM_DriverFactory.hxx"
00033 
00034 #include <vector>
00035 #include <string>
00036 #include <algorithm>
00037 
00038 using namespace MEDMEM;
00039 using namespace MED_EN;
00040 using namespace std;
00041 
00042 namespace
00043 {
00044   const char* bnd_elem_name = "Bnd elems";
00045 
00049   struct _GRID : public GRID
00050   {
00051     _GRID(const vector<vector<double> >& xyz_array,
00052           const vector<string>&          coord_name,
00053           const vector<string>&          coord_unit):
00054       GRID( xyz_array, coord_name, coord_unit ) {}
00055 
00056     void addGroup(GROUP* g)
00057     {
00058       switch ( g->getEntity() ) {
00059       case MED_CELL: _groupCell.push_back( g ); break;
00060       case MED_FACE: _groupFace.push_back( g ); break;
00061       case MED_EDGE: _groupEdge.push_back( g ); break;
00062       case MED_NODE: _groupNode.push_back( g ); break;
00063       default :throw MEDEXCEPTION(LOCALIZED("Bad Entity !"));
00064       }
00065       removeReference();
00066     }
00067   };
00068 }
00069 
00070 GRID* makeGrid(double step, double x0, double y0, int nb_x,  int nb_y, int nb_z = 0, double z0=0.)
00071 {
00072   // make grid
00073   int dim = nb_z ? 3 : 2;
00074   vector<vector<double> > xyz_array(dim);
00075   vector<string>          coord_name(dim);
00076   vector<string>          unit(dim);
00077 
00078   double origin[] = { x0, y0, z0 };
00079   int    size  [] = { nb_x, nb_y, nb_z };
00080   char name = 'X';
00081   for ( int d = 0; d < dim; ++d, ++name )
00082   {
00083     vector<double>& coords = xyz_array[d];
00084     coords.reserve( size[d]+1 );
00085     coords.push_back( origin[d] );
00086     for ( int i = 0; i < size[d]; ++i )
00087       coords.push_back( coords.back() + step );
00088 
00089     coord_name.push_back(string(1,name));
00090     unit.push_back("m");
00091   }
00092   _GRID* grid = new _GRID( xyz_array, coord_name, unit );
00093 
00094 
00095   // make group of boundary elements
00096   SUPPORT* boundary = grid->getBoundaryElements( dim == 3 ? MED_FACE : MED_EDGE );
00097 
00098   GROUP* bnd_group = new GROUP;
00099   bnd_group->setMesh( grid );
00100   bnd_group->setEntity( boundary->getEntity() );
00101   bnd_group->setName(bnd_elem_name);
00102   bnd_group->setpartial("Bnd",
00103                         boundary->getNumberOfTypes(),
00104                         boundary->getNumberOfElements(MED_ALL_ELEMENTS),
00105                         boundary->getTypes(),
00106                         boundary->getNumberOfElements(),
00107                         boundary->getNumber(MED_ALL_ELEMENTS));
00108   grid->addGroup( bnd_group );
00109  
00110   // make group on all bnd_entity's
00111   GROUP* all_bnd = new GROUP;
00112   all_bnd->setMesh( grid );
00113   all_bnd->setEntity( boundary->getEntity() );
00114   all_bnd->setName(STRING("all bnd #")<<x0<<y0<<nb_x<<nb_x<<nb_z<<z0);
00115   all_bnd->setAll( true );
00116   all_bnd->update();
00117   grid->addGroup( all_bnd );
00118 
00119   boundary->removeReference();
00120   
00121 
00122   return grid;
00123 }
00124 
00125 void MEDMEMTest::testMeshFuse()
00126 {
00127   // fuse two grids:
00128   // first | second
00129   //
00130   //  5   6
00131   //   *---*
00132   //  3|  4| 10
00133   //   *---*---*
00134   //  1|  2|  9|
00135   //   *---*---*
00136   //      7|  8|
00137   //       *---*
00138 
00139   int gnl [] = {1,2,3,4,5,6 };
00140   int gnr [] = {7,8,2,9,4,10};
00141   const int nb_x = 1, nb_y = 2, nb_z = 3;
00142 
00143   // make grids
00144   const double step = 10;
00145   const GRID* grid_left  = makeGrid(step, 0,0,       nb_x,nb_y);
00146   const GRID* grid_right = makeGrid(step, step,-step,nb_x,nb_y);
00147   const MESH* mesh_left  = grid_left->convertInMESH();
00148   const MESH* mesh_right = grid_right->convertInMESH();
00149 
00150   // compute families
00151   const_cast<MESH*>( mesh_left )->createFamilies();
00152   const_cast<MESH*>( mesh_right )->createFamilies();
00153 
00154   // global node numbers
00155   vector<int> glob_nb_left ( gnl, ((int*)gnl) + 6 );
00156   vector<int> glob_nb_right( gnr, ((int*)gnr) + 6 );
00157 
00158   // fuse two 2D grids
00159   {
00160     MeshFuse fusion;
00161     fusion.concatenate(mesh_left,  glob_nb_left);
00162     fusion.concatenate(mesh_right, glob_nb_right);
00163 
00164     const medEntityMesh sub_entity = MED_EDGE;
00165 
00166     // check number of nodes and elements
00167     const int nb_common_nodes = 2;
00168     const int expect_nb_nodes = 2 * grid_left->getNumberOfNodes() - nb_common_nodes;
00169     CPPUNIT_ASSERT_EQUAL( expect_nb_nodes, fusion.getNumberOfNodes());
00170 
00171     const int expect_nb_cells = 2 * grid_left->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS);
00172     CPPUNIT_ASSERT_EQUAL( expect_nb_cells, fusion.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS));
00173 
00174     CPPUNIT_ASSERT_EQUAL( 7, grid_left->getNumberOfElements( sub_entity, MED_ALL_ELEMENTS ));
00175 
00176     const int nb_common_edges = 1;
00177     const int expect_nb_edges =
00178       2 * grid_left->getNumberOfElements(sub_entity, MED_ALL_ELEMENTS) - nb_common_edges;
00179     CPPUNIT_ASSERT_EQUAL( expect_nb_edges, fusion.getNumberOfElements(sub_entity, MED_ALL_ELEMENTS));
00180 
00181     // check groups
00182     const GROUP* bnd_edges = 0;
00183     CPPUNIT_ASSERT_NO_THROW( bnd_edges = fusion.getGroup( bnd_elem_name ));
00184     CPPUNIT_ASSERT( !bnd_edges->isOnAllElements() );
00185 
00186     const int nb_bnd_edges =
00187       grid_left->getGroup( bnd_elem_name )->getNumberOfElements(MED_ALL_ELEMENTS);
00188     const int expect_nb_bnd = 2 * nb_bnd_edges - nb_common_edges;
00189     CPPUNIT_ASSERT_EQUAL( expect_nb_bnd, bnd_edges->getNumberOfElements(MED_ALL_ELEMENTS));
00190 
00191     // check families
00192     set<string> oldFamNames;
00193     vector<FAMILY*> fams = mesh_left->getFamilies(sub_entity);
00194     for (int i = 0; i< fams.size(); ++i ) oldFamNames.insert( fams[i]->getName());
00195     fams = mesh_right->getFamilies(sub_entity);
00196     for (int i = 0; i< fams.size(); ++i ) oldFamNames.insert( fams[i]->getName());
00197     CPPUNIT_ASSERT_EQUAL( int(oldFamNames.size()), fusion.getNumberOfFamilies( sub_entity ));
00198   }
00199   grid_left->removeReference();
00200   grid_right->removeReference();
00201   mesh_left->removeReference();
00202   mesh_right->removeReference();
00203 
00204 
00205   // Fuse two 3D grids
00206 
00207   // both grids are 1x2x3 cells,
00208   // the 2nd one is shifted by 1 cell along X, by -1 cell along Y and by 1 cell along Z
00209   // so they shares 2 faces
00210   grid_left  = makeGrid(step, 0,   0,    nb_x,nb_y,nb_z, 0.);
00211   grid_right = makeGrid(step, step,-step,nb_x,nb_y,nb_z, step);
00212   mesh_left  = grid_left->convertInMESH();
00213   mesh_right = grid_right->convertInMESH();
00214 
00215   // compute families
00216   const_cast<MESH*>( mesh_left )->createFamilies();
00217   const_cast<MESH*>( mesh_right )->createFamilies();
00218   {
00219     // global node numbers
00220     int nb_nodes = grid_left->getNumberOfNodes();
00221     glob_nb_left.resize( nb_nodes );
00222     glob_nb_right.resize( nb_nodes );
00223     for ( int n = 0; n < nb_nodes; ++n )
00224     {
00225       glob_nb_left[ n ] = n;
00226       glob_nb_right[ n ] = n + nb_nodes;
00227     }
00228     for ( int z = 0; z < nb_z; ++z )
00229       for ( int y = 1; y <= nb_y; ++y )
00230         glob_nb_right[ grid_right->getNodeNumber(0,y,z)-1 ] =
00231           glob_nb_left[ grid_left->getNodeNumber(1,y-1,z+1)-1 ];
00232 
00233     MeshFuse fusion;
00234     fusion.concatenate(mesh_left,  glob_nb_left);
00235     fusion.concatenate(mesh_right, glob_nb_right);
00236 
00237     const medEntityMesh sub_entity = MED_FACE;
00238 
00239     // check number of nodes and elements
00240     const int nb_common_nodes = 6;
00241     const int expect_nb_nodes = 2 * grid_left->getNumberOfNodes() - nb_common_nodes;
00242     CPPUNIT_ASSERT_EQUAL( expect_nb_nodes, fusion.getNumberOfNodes());
00243 
00244     const int expect_nb_cells = 2 * grid_left->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS);
00245     CPPUNIT_ASSERT_EQUAL( expect_nb_cells, fusion.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS));
00246 
00247     const int grid_nb_faces =
00248       nb_x * nb_y * (nb_z+1)+
00249       nb_x * (nb_y+1) * nb_z +
00250       (nb_x+1) * nb_y * nb_z;
00251     CPPUNIT_ASSERT_EQUAL( grid_nb_faces,
00252                           grid_left->getNumberOfElements( sub_entity, MED_ALL_ELEMENTS ));
00253 
00254     const int nb_common_faces = 2;
00255     const int expect_nb_faces =
00256       2 * grid_left->getNumberOfElements(sub_entity, MED_ALL_ELEMENTS) - nb_common_faces;
00257     CPPUNIT_ASSERT_EQUAL( expect_nb_faces,
00258                           fusion.getNumberOfElements(sub_entity, MED_ALL_ELEMENTS));
00259 
00260     // check groups
00261     const GROUP* bnd_faces = 0;
00262     CPPUNIT_ASSERT_NO_THROW( bnd_faces = fusion.getGroup( bnd_elem_name ));
00263     CPPUNIT_ASSERT( !bnd_faces->isOnAllElements() );
00264 
00265     const int nb_bnd_faces =
00266       grid_left->getGroup( bnd_elem_name )->getNumberOfElements(MED_ALL_ELEMENTS);
00267     const int expect_nb_bnd = 2 * nb_bnd_faces - nb_common_faces;
00268     CPPUNIT_ASSERT_EQUAL( expect_nb_bnd, bnd_faces->getNumberOfElements(MED_ALL_ELEMENTS));
00269 
00270     // check families
00271     CPPUNIT_ASSERT_EQUAL( 4, fusion.getNumberOfFamilies( sub_entity ));
00272   }
00273 
00274 
00275 
00276   // Fuse one 3D grid and another converted to polygons
00277 
00278   const_cast<MESH*>(mesh_right)->convertToPoly();
00279   CPPUNIT_ASSERT_EQUAL( 0, grid_right->getNumberOfElements(MED_CELL, MED_QUAD4));
00280   {
00281     MeshFuse fusion;
00282     fusion.concatenate(mesh_left,  glob_nb_left);
00283     fusion.concatenate(mesh_right, glob_nb_right);
00284 
00285     const medEntityMesh sub_entity = MED_FACE;
00286 
00287     // check number of nodes and elements
00288     const int nb_common_nodes = 6;
00289     const int expect_nb_nodes = 2 * grid_left->getNumberOfNodes() - nb_common_nodes;
00290     CPPUNIT_ASSERT_EQUAL( expect_nb_nodes, fusion.getNumberOfNodes());
00291 
00292     const int expect_nb_cells = 2 * grid_left->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS);
00293     CPPUNIT_ASSERT_EQUAL( expect_nb_cells,
00294                           fusion.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS));
00295 
00296     const int grid_nb_faces =
00297       nb_x * nb_y * (nb_z+1)+
00298       nb_x * (nb_y+1) * nb_z +
00299       (nb_x+1) * nb_y * nb_z;
00300     CPPUNIT_ASSERT_EQUAL( grid_nb_faces,
00301                           grid_left->getNumberOfElements( sub_entity, MED_ALL_ELEMENTS ));
00302 
00303     const int nb_common_faces = 2;
00304     const int expect_nb_faces =
00305       2 * grid_left->getNumberOfElements(sub_entity, MED_ALL_ELEMENTS) - nb_common_faces;
00306     CPPUNIT_ASSERT_EQUAL( expect_nb_faces,
00307                           fusion.getNumberOfElements(sub_entity, MED_ALL_ELEMENTS));
00308 
00309     // check groups
00310     const GROUP* bnd_faces = 0;
00311     CPPUNIT_ASSERT_NO_THROW( bnd_faces = fusion.getGroup( bnd_elem_name ));
00312     CPPUNIT_ASSERT( !bnd_faces->isOnAllElements() );
00313 
00314     const int nb_bnd_faces =
00315       grid_left->getGroup( bnd_elem_name )->getNumberOfElements(MED_ALL_ELEMENTS);
00316      // convertToPoly does not convert groups and families
00317     const int expect_nb_bnd = 2 * nb_bnd_faces/* - nb_common_faces*/;
00318     CPPUNIT_ASSERT_EQUAL( expect_nb_bnd, bnd_faces->getNumberOfElements(MED_ALL_ELEMENTS));
00319 
00320     // check families
00321     CPPUNIT_ASSERT_EQUAL( 4, fusion.getNumberOfFamilies( sub_entity ));
00322   }
00323 
00324   grid_left->removeReference();
00325   grid_right->removeReference();
00326   mesh_left->removeReference();
00327   mesh_right->removeReference();
00328 
00329 }