MOAB: Mesh Oriented datABase  (version 5.4.1)
visuMapVtk.cpp
Go to the documentation of this file.
00001 /*
00002  * visuMapVtk.cpp
00003  * this tool will take a source file, target file (h5m) and a map file in nc format,
00004  *
00005  * example of usage:
00006  * ./mbvisumap -s source.h5m -t target.h5m -m map.nc -b startSourceID -e endSourceID  -c startTargetID -f endTargetID
00007  * will associate row i in map with a partial mesh
00008  *  will associate row j in map with a partial mesh
00009  *
00010  * can be built only if netcdf and hdf5 and eigen3 are available
00011  *
00012  *
00013  */
00014 #include "moab/MOABConfig.h"
00015 
00016 #ifndef MOAB_HAVE_EIGEN3
00017 #error compareMaps tool requires eigen3 configuration
00018 #endif
00019 
00020 #include "moab/ProgOptions.hpp"
00021 #include "moab/Core.hpp"
00022 #include "moab/Range.hpp"
00023 
00024 #include "netcdf.h"
00025 #include <cmath>
00026 #include <sstream>
00027 #include <map>
00028 #include <Eigen/Sparse>
00029 
00030 #define ERR_NC( e )                                \
00031     {                                              \
00032         printf( "Error: %s\n", nc_strerror( e ) ); \
00033         exit( 2 );                                 \
00034     }
00035 
00036 // copy from ReadNCDF.cpp some useful macros for reading from a netcdf file (exodus?)
00037 // ncFile is an integer initialized when opening the nc file in read mode
00038 
00039 int ncFile1;
00040 
00041 #define INS_ID( stringvar, prefix, id ) sprintf( stringvar, prefix, id )
00042 
00043 #define GET_DIM1( ncdim, name, val )                            \
00044     {                                                           \
00045         int gdfail = nc_inq_dimid( ncFile1, name, &( ncdim ) ); \
00046         if( NC_NOERR == gdfail )                                \
00047         {                                                       \
00048             size_t tmp_val;                                     \
00049             gdfail = nc_inq_dimlen( ncFile1, ncdim, &tmp_val ); \
00050             if( NC_NOERR != gdfail )                            \
00051             {                                                   \
00052                 ERR_NC( gdfail )                                \
00053             }                                                   \
00054             else                                                \
00055                 ( val ) = tmp_val;                              \
00056         }                                                       \
00057         else                                                    \
00058             ( val ) = 0;                                        \
00059     }
00060 
00061 #define GET_DIMB1( ncdim, name, varname, id, val ) \
00062     INS_ID( name, varname, id );                   \
00063     GET_DIM1( ncdim, name, val );
00064 
00065 #define GET_VAR1( name, id, dims )                                     \
00066     {                                                                  \
00067         ( id )     = -1;                                               \
00068         int gvfail = nc_inq_varid( ncFile1, name, &( id ) );           \
00069         if( NC_NOERR == gvfail )                                       \
00070         {                                                              \
00071             int ndims;                                                 \
00072             gvfail = nc_inq_varndims( ncFile1, id, &ndims );           \
00073             if( NC_NOERR == gvfail )                                   \
00074             {                                                          \
00075                 ( dims ).resize( ndims );                              \
00076                 gvfail = nc_inq_vardimid( ncFile1, id, &( dims )[0] ); \
00077                 if( NC_NOERR != gvfail )                               \
00078                 {                                                      \
00079                     ERR_NC( gvfail )                                   \
00080                 }                                                      \
00081             }                                                          \
00082         }                                                              \
00083     }
00084 
00085 #define GET_1D_INT_VAR1( name, id, vals )                                               \
00086     {                                                                                   \
00087         GET_VAR1( name, id, vals );                                                     \
00088         if( -1 != ( id ) )                                                              \
00089         {                                                                               \
00090             size_t ntmp;                                                                \
00091             int ivfail = nc_inq_dimlen( ncFile1, ( vals )[0], &ntmp );                  \
00092             if( NC_NOERR != ivfail )                                                    \
00093             {                                                                           \
00094                 ERR_NC( ivfail )                                                        \
00095             }                                                                           \
00096             ( vals ).resize( ntmp );                                                    \
00097             size_t ntmp1 = 0;                                                           \
00098             ivfail       = nc_get_vara_int( ncFile1, id, &ntmp1, &ntmp, &( vals )[0] ); \
00099             if( NC_NOERR != ivfail )                                                    \
00100             {                                                                           \
00101                 ERR_NC( ivfail )                                                        \
00102             }                                                                           \
00103         }                                                                               \
00104     }
00105 
00106 #define GET_1D_DBL_VAR1( name, id, vals )                                                  \
00107     {                                                                                      \
00108         std::vector< int > dum_dims;                                                       \
00109         GET_VAR1( name, id, dum_dims );                                                    \
00110         if( -1 != ( id ) )                                                                 \
00111         {                                                                                  \
00112             size_t ntmp;                                                                   \
00113             int dvfail = nc_inq_dimlen( ncFile1, dum_dims[0], &ntmp );                     \
00114             if( NC_NOERR != dvfail )                                                       \
00115             {                                                                              \
00116                 ERR_NC( dvfail )                                                           \
00117             }                                                                              \
00118             ( vals ).resize( ntmp );                                                       \
00119             size_t ntmp1 = 0;                                                              \
00120             dvfail       = nc_get_vara_double( ncFile1, id, &ntmp1, &ntmp, &( vals )[0] ); \
00121             if( NC_NOERR != dvfail )                                                       \
00122             {                                                                              \
00123                 ERR_NC( dvfail )                                                           \
00124             }                                                                              \
00125         }                                                                                  \
00126     }
00127 
00128 using namespace moab;
00129 using namespace std;
00130 
00131 int main( int argc, char* argv[] )
00132 {
00133 
00134     ProgOptions opts;
00135     int dimSource = 2;  // for FV meshes is 2; for SE meshes, use fine mesh, dim will be 0
00136     int dimTarget = 2;  //
00137     int otype     = 0;
00138 
00139     std::string inputfile1, inputSource, inputTarget;
00140     opts.addOpt< std::string >( "map,m", "input map ", &inputfile1 );
00141     opts.addOpt< std::string >( "source,s", "source mesh", &inputSource );
00142     opts.addOpt< std::string >( "target,t", "target mesh", &inputTarget );
00143     opts.addOpt< int >( "dimSource,d", "dimension of source  ", &dimSource );
00144     opts.addOpt< int >( "dimTarget,g", "dimension of target  ", &dimTarget );
00145     opts.addOpt< int >( "typeOutput,o", " output type vtk(0), h5m(1)", &otype );
00146 
00147     int startSourceID = -1, endSourceID = -1, startTargetID = -1, endTargetID = -1;
00148     opts.addOpt< int >( "startSourceID,b", "start source id ", &startSourceID );
00149     opts.addOpt< int >( "endSourceID,e", "end source id ", &endSourceID );
00150     opts.addOpt< int >( "startTargetID,c", "start target id ", &startTargetID );
00151     opts.addOpt< int >( "endTargetID,f", "end target id ", &endTargetID );
00152     //  -b startSourceID -e endSourceID  -c startTargetID -f endTargetID
00153 
00154     opts.parseCommandLine( argc, argv );
00155 
00156     std::string extension = ".vtk";
00157     if( 1 == otype ) extension = ".h5m";
00158     // Open netcdf/exodus file
00159     int fail = nc_open( inputfile1.c_str(), 0, &ncFile1 );
00160     if( NC_NOWRITE != fail )
00161     {
00162         ERR_NC( fail )
00163     }
00164 
00165     std::cout << " opened " << inputfile1 << " for map 1 \n";
00166 
00167     int temp_dim;
00168     int na1, nb1, ns1;
00169     GET_DIM1( temp_dim, "n_a", na1 );
00170     GET_DIM1( temp_dim, "n_b", nb1 );
00171     GET_DIM1( temp_dim, "n_s", ns1 );
00172     std::cout << " n_a, n_b, n_s : " << na1 << ", " << nb1 << ", " << ns1 << " for map 1 \n";
00173     std::vector< int > col1( ns1 ), row1( ns1 );
00174     std::vector< double > val1( ns1 );
00175     int idrow1, idcol1, ids1;
00176     GET_1D_INT_VAR1( "row", idrow1, row1 );
00177     GET_1D_INT_VAR1( "col", idcol1, col1 );
00178     GET_1D_DBL_VAR1( "S", ids1, val1 );
00179     // first matrix
00180     typedef Eigen::Triplet< double > Triplet;
00181     std::vector< Triplet > tripletList;
00182     tripletList.reserve( ns1 );
00183     for( int iv = 0; iv < ns1; iv++ )
00184     {
00185         // all row and column indices are 1-based in the map file.
00186         // inside Eigen3, we will use 0-based; then we will have to add back 1 when
00187         //     we dump out the files
00188         tripletList.push_back( Triplet( row1[iv] - 1, col1[iv] - 1, val1[iv] ) );
00189     }
00190     Eigen::SparseMatrix< double > weight1( nb1, na1 );
00191 
00192     weight1.setFromTriplets( tripletList.begin(), tripletList.end() );
00193     weight1.makeCompressed();
00194     // we read the matrix; now read moab source and target
00195     Core core;
00196     Interface* mb = &core;
00197     ErrorCode rval;
00198     Tag gtag = mb->globalId_tag();
00199     EntityHandle sourceSet, targetSet;
00200     // those are the maps from global ids to the moab entity handles corresponding to those global ids
00201     //   which are corresponding to the global DOFs
00202     map< int, EntityHandle > sourceHandles;
00203     map< int, EntityHandle > targetHandles;
00204     rval = mb->create_meshset( MESHSET_SET, sourceSet );MB_CHK_SET_ERR( rval, "can't create source mesh set" );
00205     rval = mb->create_meshset( MESHSET_SET, targetSet );MB_CHK_SET_ERR( rval, "can't create target mesh set" );
00206     const char* readopts = "";
00207     rval                 = mb->load_file( inputSource.c_str(), &sourceSet, readopts );MB_CHK_SET_ERR( rval, "Failed to read" );
00208     rval = mb->load_file( inputTarget.c_str(), &targetSet, readopts );MB_CHK_SET_ERR( rval, "Failed to read" );
00209     Range sRange;
00210     rval = mb->get_entities_by_dimension( sourceSet, dimSource, sRange );MB_CHK_SET_ERR( rval, "Failed to get sRange" );
00211     vector< int > sids;
00212     sids.resize( sRange.size() );
00213     rval = mb->tag_get_data( gtag, sRange, &sids[0] );MB_CHK_SET_ERR( rval, "Failed to get ids for srange" );
00214     // all global ids are 1 based in the source file, and they correspond to the dofs in the map file
00215     for( size_t i = 0; i < sids.size(); i++ )
00216     {
00217         EntityHandle eh    = sRange[i];
00218         int gid            = sids[i];
00219         sourceHandles[gid] = eh;
00220     }
00221     Range tRange;
00222     rval = mb->get_entities_by_dimension( targetSet, dimTarget, tRange );MB_CHK_SET_ERR( rval, "Failed to get tRange" );
00223     vector< int > tids;
00224     tids.resize( tRange.size() );
00225     rval = mb->tag_get_data( gtag, tRange, &tids[0] );MB_CHK_SET_ERR( rval, "Failed to get ids for trange" );
00226     // all global ids are 1 based in the target file, and they correspond to the dofs in the map file
00227     for( size_t i = 0; i < tids.size(); i++ )
00228     {
00229         EntityHandle eh    = tRange[i];
00230         int gid            = tids[i];
00231         targetHandles[gid] = eh;
00232     }
00233     // a dense tag for weights
00234     Tag wtag;
00235     double defVal = 0;
00236 
00237     std::string name_map = inputfile1;
00238     // strip last 3 chars (.nc extension)
00239     name_map.erase( name_map.begin() + name_map.length() - 3, name_map.end() );
00240     // if path , remove from name
00241     size_t pos = name_map.rfind( '/', name_map.length() );
00242     if( pos != std::string::npos ) name_map = name_map.erase( 0, pos + 1 );
00243 
00244     rval = mb->tag_get_handle( "weight", 1, MB_TYPE_DOUBLE, wtag, MB_TAG_CREAT | MB_TAG_DENSE, &defVal );MB_CHK_SET_ERR( rval, "Failed to create weight" );
00245     EntityHandle partialSet;
00246     rval = mb->create_meshset( MESHSET_SET, partialSet );MB_CHK_SET_ERR( rval, "can't create partial set" );
00247     // how to get a complete row in sparse matrix? Or a complete column ?
00248     for( int col = startSourceID - 1; col <= endSourceID - 1; col++ )
00249     {
00250         Range targetEnts;  // will find entries for column col-1 in sparse matrix weight1, and its entries
00251         // will assign a dense tag with values, and write out the file
00252         if( col < 0 ) continue;
00253         Eigen::SparseVector< double > colVect = weight1.col( col );
00254         // the row indices correspond to target cells
00255         for( Eigen::SparseVector< double >::InnerIterator it( colVect ); it; ++it )
00256         {
00257             double weight = it.value();  // == vec[ it.index() ]
00258                                          // we add back the 1 that we subtract
00259             int globalIdRow = it.index() + 1;
00260             EntityHandle th = targetHandles[globalIdRow];
00261             targetEnts.insert( th );
00262             rval = mb->tag_set_data( wtag, &th, 1, &weight );MB_CHK_SET_ERR( rval, "Failed to set weight tag on target" );
00263         }
00264 
00265         if( dimTarget == 0 )
00266         {
00267             Range adjCells;
00268             rval = mb->get_adjacencies( targetEnts, 2, false, adjCells, Interface::UNION );MB_CHK_SET_ERR( rval, " can't get adj cells " );
00269             targetEnts.merge( adjCells );
00270         }
00271 
00272         rval = mb->add_entities( partialSet, targetEnts );MB_CHK_SET_ERR( rval, "Failed to add target entities to partial set" );
00273         // write now the set in a numbered file
00274         std::stringstream fff;
00275         fff << name_map << "_column" << col + 1 << extension;
00276         rval = mb->write_mesh( fff.str().c_str(), &partialSet, 1 );MB_CHK_ERR( rval );
00277         // remove from partial set the entities it has
00278         rval = mb->clear_meshset( &partialSet, 1 );MB_CHK_SET_ERR( rval, "Failed to empty partial set" );
00279     }
00280 
00281     // how to get a complete row in sparse matrix?
00282     for( int row = startTargetID - 1; row <= endTargetID - 1; row++ )
00283     {
00284         Range sourceEnts;  // will find entries for row in sparse matrix weight1, and its entries
00285         // will assign a dense tag with values, and write out the file
00286         if( row < 0 ) continue;
00287         Eigen::SparseVector< double > rowVect = weight1.row( row );
00288         // the row indices correspond to target cells
00289         for( Eigen::SparseVector< double >::InnerIterator it( rowVect ); it; ++it )
00290         {
00291             double weight   = it.value();  // == vec[ it.index() ]
00292             int globalIdCol = it.index() + 1;
00293             EntityHandle sh = sourceHandles[globalIdCol];
00294             sourceEnts.insert( sh );
00295             rval = mb->tag_set_data( wtag, &sh, 1, &weight );MB_CHK_SET_ERR( rval, "Failed to set weight tag on source" );
00296         }
00297         if( dimSource == 0 )
00298         {
00299             Range adjCells;
00300             rval = mb->get_adjacencies( sourceEnts, 2, false, adjCells, Interface::UNION );MB_CHK_SET_ERR( rval, " can't get adj cells " );
00301             sourceEnts.merge( adjCells );
00302         }
00303         rval = mb->add_entities( partialSet, sourceEnts );MB_CHK_SET_ERR( rval, "Failed to add source entities" );
00304         // write now the set in a numbered file
00305         std::stringstream fff;
00306         fff << name_map << "_row" << row + 1 << extension;
00307         rval = mb->write_mesh( fff.str().c_str(), &partialSet, 1 );MB_CHK_ERR( rval );
00308         rval = mb->clear_meshset( &partialSet, 1 );MB_CHK_SET_ERR( rval, "Failed to empty partial set" );
00309     }
00310     return 0;
00311 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines