LCOV - code coverage report
Current view: top level - src/io - ReadNCDF.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 519 1087 47.7 %
Date: 2020-12-16 07:07:30 Functions: 20 25 80.0 %
Branches: 762 4866 15.7 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
       3                 :            :  * storing and accessing finite element mesh data.
       4                 :            :  *
       5                 :            :  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
       6                 :            :  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
       7                 :            :  * retains certain rights in this software.
       8                 :            :  *
       9                 :            :  * This library is free software; you can redistribute it and/or
      10                 :            :  * modify it under the terms of the GNU Lesser General Public
      11                 :            :  * License as published by the Free Software Foundation; either
      12                 :            :  * version 2.1 of the License, or (at your option) any later version.
      13                 :            :  *
      14                 :            :  */
      15                 :            : 
      16                 :            : #ifdef WIN32
      17                 :            : #pragma warning( disable : 4786 )
      18                 :            : #endif
      19                 :            : 
      20                 :            : #include "ReadNCDF.hpp"
      21                 :            : #include "netcdf.h"
      22                 :            : 
      23                 :            : #include <algorithm>
      24                 :            : #include <string>
      25                 :            : #include <assert.h>
      26                 :            : #include <stdio.h>
      27                 :            : #include <string.h>
      28                 :            : #include <cmath>
      29                 :            : #include <sstream>
      30                 :            : #include <iostream>
      31                 :            : #include <map>
      32                 :            : 
      33                 :            : #include "moab/CN.hpp"
      34                 :            : #include "moab/Range.hpp"
      35                 :            : #include "moab/Interface.hpp"
      36                 :            : #include "ExoIIUtil.hpp"
      37                 :            : #include "MBTagConventions.hpp"
      38                 :            : #include "Internals.hpp"
      39                 :            : #include "moab/ReadUtilIface.hpp"
      40                 :            : #include "exodus_order.h"
      41                 :            : #include "moab/FileOptions.hpp"
      42                 :            : #include "moab/AdaptiveKDTree.hpp"
      43                 :            : #include "moab/CartVect.hpp"
      44                 :            : 
      45                 :            : namespace moab
      46                 :            : {
      47                 :            : 
      48                 :            : #define INS_ID( stringvar, prefix, id ) sprintf( stringvar, prefix, id )
      49                 :            : 
      50                 :            : #define GET_DIM( ncdim, name, val )                                                                            \
      51                 :            :     {                                                                                                          \
      52                 :            :         int gdfail = nc_inq_dimid( ncFile, name, &ncdim );                                                     \
      53                 :            :         if( NC_NOERR == gdfail )                                                                               \
      54                 :            :         {                                                                                                      \
      55                 :            :             size_t tmp_val;                                                                                    \
      56                 :            :             gdfail = nc_inq_dimlen( ncFile, ncdim, &tmp_val );                                                 \
      57                 :            :             if( NC_NOERR != gdfail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Couldn't get dimension length" ); } \
      58                 :            :             else                                                                                               \
      59                 :            :                 val = tmp_val;                                                                                 \
      60                 :            :         }                                                                                                      \
      61                 :            :         else                                                                                                   \
      62                 :            :             val = 0;                                                                                           \
      63                 :            :     }
      64                 :            : 
      65                 :            : #define GET_DIMB( ncdim, name, varname, id, val ) \
      66                 :            :     INS_ID( name, varname, id );                  \
      67                 :            :     GET_DIM( ncdim, name, val );
      68                 :            : 
      69                 :            : #define GET_VAR( name, id, dims )                                                               \
      70                 :            :     {                                                                                           \
      71                 :            :         id         = -1;                                                                        \
      72                 :            :         int gvfail = nc_inq_varid( ncFile, name, &id );                                         \
      73                 :            :         if( NC_NOERR == gvfail )                                                                \
      74                 :            :         {                                                                                       \
      75                 :            :             int ndims;                                                                          \
      76                 :            :             gvfail = nc_inq_varndims( ncFile, id, &ndims );                                     \
      77                 :            :             if( NC_NOERR == gvfail )                                                            \
      78                 :            :             {                                                                                   \
      79                 :            :                 dims.resize( ndims );                                                           \
      80                 :            :                 gvfail = nc_inq_vardimid( ncFile, id, &dims[0] );                               \
      81                 :            :                 if( NC_NOERR != gvfail )                                                        \
      82                 :            :                 { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Couldn't get variable dimension IDs" ); } \
      83                 :            :             }                                                                                   \
      84                 :            :         }                                                                                       \
      85                 :            :     }
      86                 :            : 
      87                 :            : #define GET_1D_INT_VAR( name, id, vals )                                                                           \
      88                 :            :     {                                                                                                              \
      89                 :            :         GET_VAR( name, id, vals );                                                                                 \
      90                 :            :         if( -1 != id )                                                                                             \
      91                 :            :         {                                                                                                          \
      92                 :            :             size_t ntmp;                                                                                           \
      93                 :            :             int ivfail = nc_inq_dimlen( ncFile, vals[0], &ntmp );                                                  \
      94                 :            :             if( NC_NOERR != ivfail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Couldn't get dimension length" ); }     \
      95                 :            :             vals.resize( ntmp );                                                                                   \
      96                 :            :             size_t ntmp1 = 0;                                                                                      \
      97                 :            :             ivfail       = nc_get_vara_int( ncFile, id, &ntmp1, &ntmp, &vals[0] );                                 \
      98                 :            :             if( NC_NOERR != ivfail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting variable " << name ); } \
      99                 :            :         }                                                                                                          \
     100                 :            :     }
     101                 :            : 
     102                 :            : #define GET_1D_DBL_VAR( name, id, vals )                                                                           \
     103                 :            :     {                                                                                                              \
     104                 :            :         std::vector< int > dum_dims;                                                                               \
     105                 :            :         GET_VAR( name, id, dum_dims );                                                                             \
     106                 :            :         if( -1 != id )                                                                                             \
     107                 :            :         {                                                                                                          \
     108                 :            :             size_t ntmp;                                                                                           \
     109                 :            :             int dvfail = nc_inq_dimlen( ncFile, dum_dims[0], &ntmp );                                              \
     110                 :            :             if( NC_NOERR != dvfail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Couldn't get dimension length" ); }     \
     111                 :            :             vals.resize( ntmp );                                                                                   \
     112                 :            :             size_t ntmp1 = 0;                                                                                      \
     113                 :            :             dvfail       = nc_get_vara_double( ncFile, id, &ntmp1, &ntmp, &vals[0] );                              \
     114                 :            :             if( NC_NOERR != dvfail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting variable " << name ); } \
     115                 :            :         }                                                                                                          \
     116                 :            :     }
     117                 :            : 
     118                 :         26 : ReaderIface* ReadNCDF::factory( Interface* iface )
     119                 :            : {
     120         [ +  - ]:         26 :     return new ReadNCDF( iface );
     121                 :            : }
     122                 :            : 
     123 [ +  - ][ +  - ]:         52 : ReadNCDF::ReadNCDF( Interface* impl ) : mdbImpl( impl ), max_line_length( -1 ), max_str_length( -1 )
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     124                 :            : {
     125         [ -  + ]:         26 :     assert( impl != NULL );
     126         [ +  - ]:         26 :     reset();
     127                 :            : 
     128         [ +  - ]:         26 :     impl->query_interface( readMeshIface );
     129                 :            : 
     130                 :            :     // Initialize in case tag_get_handle fails below
     131                 :         26 :     mMaterialSetTag  = 0;
     132                 :         26 :     mDirichletSetTag = 0;
     133                 :         26 :     mNeumannSetTag   = 0;
     134                 :         26 :     mHasMidNodesTag  = 0;
     135                 :         26 :     mDistFactorTag   = 0;
     136                 :         26 :     mQaRecordTag     = 0;
     137                 :         26 :     mGlobalIdTag     = 0;
     138                 :            : 
     139                 :            :     //! Get and cache predefined tag handles
     140                 :            :     ErrorCode result;
     141                 :         26 :     const int negone = -1;
     142                 :            :     result           = impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag,
     143         [ +  - ]:         26 :                                    MB_TAG_SPARSE | MB_TAG_CREAT, &negone );
     144         [ -  + ]:         26 :     assert( MB_SUCCESS == result );
     145                 :            :     result = impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag,
     146         [ +  - ]:         26 :                                    MB_TAG_SPARSE | MB_TAG_CREAT, &negone );
     147         [ -  + ]:         26 :     assert( MB_SUCCESS == result );
     148                 :            :     result = impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag,
     149         [ +  - ]:         26 :                                    MB_TAG_SPARSE | MB_TAG_CREAT, &negone );
     150         [ -  + ]:         26 :     assert( MB_SUCCESS == result );
     151                 :         26 :     const int mids[] = { -1, -1, -1, -1 };
     152                 :            :     result           = impl->tag_get_handle( HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER, mHasMidNodesTag,
     153         [ +  - ]:         26 :                                    MB_TAG_SPARSE | MB_TAG_CREAT, mids );
     154         [ -  + ]:         26 :     assert( MB_SUCCESS == result );
     155                 :            :     result = impl->tag_get_handle( "distFactor", 0, MB_TYPE_DOUBLE, mDistFactorTag,
     156         [ +  - ]:         26 :                                    MB_TAG_SPARSE | MB_TAG_VARLEN | MB_TAG_CREAT );
     157         [ -  + ]:         26 :     assert( MB_SUCCESS == result );
     158                 :            :     result = impl->tag_get_handle( "qaRecord", 0, MB_TYPE_OPAQUE, mQaRecordTag,
     159         [ +  - ]:         26 :                                    MB_TAG_SPARSE | MB_TAG_VARLEN | MB_TAG_CREAT );
     160         [ -  + ]:         26 :     assert( MB_SUCCESS == result );
     161         [ +  - ]:         26 :     mGlobalIdTag = impl->globalId_tag();
     162                 :            : 
     163         [ -  + ]:         26 :     assert( MB_SUCCESS == result );
     164                 :            : #ifdef NDEBUG
     165                 :            :     if( MB_SUCCESS == result ) {};  // Line to avoid compiler warning about unused variable
     166                 :            : #endif
     167                 :         26 :     ncFile = 0;
     168                 :         26 : }
     169                 :            : 
     170                 :         52 : void ReadNCDF::reset()
     171                 :            : {
     172                 :         52 :     mCurrentMeshHandle = 0;
     173                 :         52 :     vertexOffset       = 0;
     174                 :            : 
     175                 :         52 :     numberNodes_loading         = 0;
     176                 :         52 :     numberElements_loading      = 0;
     177                 :         52 :     numberElementBlocks_loading = 0;
     178                 :         52 :     numberFaceBlocks_loading    = 0;
     179                 :         52 :     numberNodeSets_loading      = 0;
     180                 :         52 :     numberSideSets_loading      = 0;
     181                 :         52 :     numberDimensions_loading    = 0;
     182                 :            : 
     183         [ -  + ]:         52 :     if( !blocksLoading.empty() ) blocksLoading.clear();
     184                 :            : 
     185         [ -  + ]:         52 :     if( !nodesInLoadedBlocks.empty() ) nodesInLoadedBlocks.clear();
     186                 :            : 
     187         [ -  + ]:         52 :     if( !faceBlocksLoading.empty() ) faceBlocksLoading.clear();
     188                 :         52 : }
     189                 :            : 
     190                 :         78 : ReadNCDF::~ReadNCDF()
     191                 :            : {
     192                 :         26 :     mdbImpl->release_interface( readMeshIface );
     193         [ -  + ]:         52 : }
     194                 :            : 
     195                 :          0 : ErrorCode ReadNCDF::read_tag_values( const char* file_name, const char* tag_name, const FileOptions& /* opts */,
     196                 :            :                                      std::vector< int >& id_array, const SubsetList* subset_list )
     197                 :            : {
     198         [ #  # ]:          0 :     if( subset_list )
     199 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "ExodusII reader supports subset read only by material ID" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     200                 :            : 
     201                 :            :     // Open netcdf/exodus file
     202                 :          0 :     int fail = nc_open( file_name, 0, &ncFile );
     203         [ #  # ]:          0 :     if( NC_NOWRITE != fail )
     204 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, "ReadNCDF:: problem opening Netcdf/Exodus II file " << file_name ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     205                 :            : 
     206                 :            :     // 1. Read the header
     207                 :          0 :     ErrorCode rval = read_exodus_header();
     208         [ #  # ]:          0 :     if( MB_FAILURE == rval ) return rval;
     209                 :            : 
     210                 :          0 :     int count = 0;
     211                 :            :     const char* prop;
     212                 :          0 :     const char* blocks   = "eb_prop1";
     213                 :          0 :     const char* nodesets = "ns_prop1";
     214                 :          0 :     const char* sidesets = "ss_prop1";
     215                 :            : 
     216         [ #  # ]:          0 :     if( !strcmp( tag_name, MATERIAL_SET_TAG_NAME ) )
     217                 :            :     {
     218                 :          0 :         count = numberElementBlocks_loading;
     219                 :          0 :         prop  = blocks;
     220                 :            :     }
     221         [ #  # ]:          0 :     else if( !strcmp( tag_name, DIRICHLET_SET_TAG_NAME ) )
     222                 :            :     {
     223                 :          0 :         count = numberNodeSets_loading;
     224                 :          0 :         prop  = nodesets;
     225                 :            :     }
     226         [ #  # ]:          0 :     else if( !strcmp( tag_name, NEUMANN_SET_TAG_NAME ) )
     227                 :            :     {
     228                 :          0 :         count = numberSideSets_loading;
     229                 :          0 :         prop  = sidesets;
     230                 :            :     }
     231                 :            :     else
     232                 :            :     {
     233                 :          0 :         ncFile = 0;
     234                 :          0 :         return MB_TAG_NOT_FOUND;
     235                 :            :     }
     236                 :            : 
     237         [ #  # ]:          0 :     if( count )
     238                 :            :     {
     239                 :          0 :         int nc_var = -1;
     240 [ #  # ][ #  # ]:          0 :         GET_1D_INT_VAR( prop, nc_var, id_array );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     241 [ #  # ][ #  # ]:          0 :         if( !nc_var ) { MB_SET_ERR( MB_FAILURE, "Problem getting prop variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     242                 :            :     }
     243                 :            : 
     244                 :            :     // Close the file
     245                 :          0 :     fail = nc_close( ncFile );
     246 [ #  # ][ #  # ]:          0 :     if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "Trouble closing file" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     247                 :            : 
     248                 :          0 :     ncFile = 0;
     249                 :          0 :     return MB_SUCCESS;
     250                 :            : }
     251                 :            : 
     252                 :         26 : ErrorCode ReadNCDF::load_file( const char* exodus_file_name, const EntityHandle* file_set, const FileOptions& opts,
     253                 :            :                                const ReaderIface::SubsetList* subset_list, const Tag* file_id_tag )
     254                 :            : {
     255                 :            :     ErrorCode status;
     256                 :            :     int fail;
     257                 :            : 
     258                 :         26 :     int num_blocks            = 0;
     259                 :         26 :     const int* blocks_to_load = 0;
     260         [ -  + ]:         26 :     if( subset_list )
     261                 :            :     {
     262 [ #  # ][ #  # ]:          0 :         if( subset_list->tag_list_length > 1 || !strcmp( subset_list->tag_list[0].tag_name, MATERIAL_SET_TAG_NAME ) )
     263 [ #  # ][ #  # ]:          0 :         { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "ExodusII reader supports subset read only by material ID" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     264         [ #  # ]:          0 :         if( subset_list->num_parts )
     265 [ #  # ][ #  # ]:          0 :         { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "ExodusII reader does not support mesh partitioning" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     266                 :          0 :         blocks_to_load = subset_list->tag_list[0].tag_values;
     267                 :          0 :         num_blocks     = subset_list->tag_list[0].num_tag_values;
     268                 :            :     }
     269                 :            : 
     270                 :            :     // This function directs the reading of an exoii file, but doesn't do any of
     271                 :            :     // the actual work
     272                 :            : 
     273                 :            :     // See if opts has tdata.
     274                 :            :     ErrorCode rval;
     275         [ +  - ]:         26 :     std::string s;
     276         [ +  - ]:         26 :     rval = opts.get_str_option( "tdata", s );
     277 [ -  + ][ #  # ]:         26 :     if( MB_SUCCESS == rval && !s.empty() )
                 [ -  + ]
     278         [ #  # ]:          0 :         return update( exodus_file_name, opts, num_blocks, blocks_to_load, *file_set );
     279                 :            : 
     280         [ +  - ]:         26 :     reset();
     281                 :            : 
     282                 :            :     // 0. Open the file.
     283                 :            : 
     284                 :            :     // open netcdf/exodus file
     285         [ +  - ]:         26 :     fail = nc_open( exodus_file_name, 0, &ncFile );
     286         [ +  + ]:         26 :     if( NC_NOERR != fail )
     287 [ +  - ][ +  - ]:          1 :     { MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, "ReadNCDF:: problem opening Netcdf/Exodus II file " << exodus_file_name ); }
         [ +  - ][ +  - ]
         [ -  + ][ +  - ]
     288                 :            : 
     289                 :            :     // 1. Read the header
     290         [ +  - ]:         25 :     status = read_exodus_header();
     291         [ -  + ]:         25 :     if( MB_FAILURE == status ) return status;
     292                 :            : 
     293         [ +  - ]:         25 :     status = mdbImpl->get_entities_by_handle( 0, initRange );
     294         [ -  + ]:         25 :     if( MB_FAILURE == status ) return status;
     295                 :            : 
     296                 :            :     // 2. Read the nodes unless they've already been read before
     297         [ +  - ]:         25 :     status = read_nodes( file_id_tag );
     298         [ -  + ]:         25 :     if( MB_FAILURE == status ) return status;
     299                 :            : 
     300                 :            :     // 3.
     301                 :            :     // extra for polyhedra blocks
     302         [ -  + ]:         25 :     if( numberFaceBlocks_loading > 0 )
     303                 :            :     {
     304         [ #  # ]:          0 :         status = read_face_blocks_headers();
     305         [ #  # ]:          0 :         if( MB_FAILURE == status ) return status;
     306                 :            :     }
     307                 :            : 
     308         [ +  - ]:         25 :     status = read_block_headers( blocks_to_load, num_blocks );
     309         [ -  + ]:         25 :     if( MB_FAILURE == status ) return status;
     310                 :            : 
     311                 :            :     // 4. Read elements (might not read them, depending on active blocks)
     312         [ -  + ]:         25 :     if( numberFaceBlocks_loading > 0 )
     313                 :            :     {
     314         [ #  # ]:          0 :         status = read_polyhedra_faces();
     315         [ #  # ]:          0 :         if( MB_FAILURE == status ) return status;
     316                 :            :     }
     317         [ +  - ]:         25 :     status = read_elements( file_id_tag );
     318         [ -  + ]:         25 :     if( MB_FAILURE == status ) return status;
     319                 :            : 
     320                 :            :     // 5. Read global ids
     321         [ +  - ]:         25 :     status = read_global_ids();
     322         [ -  + ]:         25 :     if( MB_FAILURE == status ) return status;
     323                 :            : 
     324                 :            :     // 6. Read nodesets
     325         [ +  - ]:         25 :     status = read_nodesets();
     326         [ -  + ]:         25 :     if( MB_FAILURE == status ) return status;
     327                 :            : 
     328                 :            :     // 7. Read sidesets
     329         [ +  - ]:         25 :     status = read_sidesets();
     330         [ -  + ]:         25 :     if( MB_FAILURE == status ) return status;
     331                 :            : 
     332                 :            :     // 8. Read qa records
     333         [ +  + ]:         25 :     if( file_set )
     334                 :            :     {
     335         [ +  - ]:          2 :         status = read_qa_records( *file_set );
     336         [ -  + ]:          2 :         if( MB_FAILURE == status ) return status;
     337                 :            :     }
     338                 :            : 
     339                 :            :     // What about properties???
     340                 :            : 
     341                 :            :     // Close the file
     342         [ +  - ]:         25 :     fail = nc_close( ncFile );
     343 [ -  + ][ #  # ]:         25 :     if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "Trouble closing file" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     344                 :            : 
     345                 :         25 :     ncFile = 0;
     346                 :         26 :     return MB_SUCCESS;
     347                 :            : }
     348                 :            : 
     349                 :         25 : ErrorCode ReadNCDF::read_exodus_header()
     350                 :            : {
     351                 :         25 :     CPU_WORD_SIZE = sizeof( double );  // With ExodusII version 2, all floats
     352                 :         25 :     IO_WORD_SIZE  = sizeof( double );  // should be changed to doubles
     353                 :            : 
     354                 :            :     // NetCDF doesn't check its own limits on file read, so check
     355                 :            :     // them here so it doesn't corrupt memory any more than absolutely
     356                 :            :     // necessary.
     357                 :            :     int ndims;
     358         [ +  - ]:         25 :     int fail = nc_inq_ndims( ncFile, &ndims );
     359 [ +  - ][ -  + ]:         25 :     if( NC_NOERR != fail || ndims > NC_MAX_DIMS )
     360                 :            :     {
     361 [ #  # ][ #  # ]:          0 :         MB_SET_ERR( MB_FAILURE, "ReadNCDF: File contains " << ndims << " dims but NetCDF library supports only "
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     362                 :            :                                                            << (int)NC_MAX_DIMS );
     363                 :            :     }
     364                 :            :     int nvars;
     365         [ +  - ]:         25 :     fail = nc_inq_nvars( ncFile, &nvars );
     366         [ -  + ]:         25 :     if( nvars > NC_MAX_VARS )
     367                 :            :     {
     368 [ #  # ][ #  # ]:          0 :         MB_SET_ERR( MB_FAILURE, "ReadNCDF: File contains " << nvars << " vars but NetCDF library supports only "
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     369                 :            :                                                            << (int)NC_MAX_VARS );
     370                 :            :     }
     371                 :            : 
     372                 :            :     // Get the attributes
     373                 :            : 
     374                 :            :     // Get the word size, scalar value
     375                 :            :     nc_type att_type;
     376                 :            :     size_t att_len;
     377         [ +  - ]:         25 :     fail = nc_inq_att( ncFile, NC_GLOBAL, "floating_point_word_size", &att_type, &att_len );
     378         [ -  + ]:         25 :     if( NC_NOERR != fail )
     379 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting floating_point_word_size attribute" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     380 [ +  - ][ -  + ]:         25 :     if( att_type != NC_INT || att_len != 1 )
     381 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Word size didn't have type int or size 1" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     382         [ +  - ]:         25 :     fail = nc_get_att_int( ncFile, NC_GLOBAL, "floating_point_word_size", &IO_WORD_SIZE );
     383 [ -  + ][ #  # ]:         25 :     if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Trouble getting word size" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     384                 :            : 
     385                 :            :     // Exodus version
     386         [ +  - ]:         25 :     fail = nc_inq_att( ncFile, NC_GLOBAL, "version", &att_type, &att_len );
     387 [ -  + ][ #  # ]:         25 :     if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting version attribute" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     388 [ +  - ][ -  + ]:         25 :     if( att_type != NC_FLOAT || att_len != 1 )
     389 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Version didn't have type float or size 1" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     390                 :            :     // float version = temp_att->as_float(0);
     391                 :            : 
     392                 :            :     // Read in initial variables
     393                 :            :     int temp_dim;
     394 [ +  - ][ +  - ]:         25 :     GET_DIM( temp_dim, "num_dim", numberDimensions_loading );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     395 [ +  - ][ +  - ]:         25 :     GET_DIM( temp_dim, "num_nodes", numberNodes_loading );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     396 [ +  - ][ +  - ]:         25 :     GET_DIM( temp_dim, "num_elem", numberElements_loading );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     397 [ +  - ][ +  - ]:         25 :     GET_DIM( temp_dim, "num_el_blk", numberElementBlocks_loading );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     398 [ +  - ][ -  + ]:         25 :     GET_DIM( temp_dim, "num_fa_blk", numberFaceBlocks_loading );  // for polyhedra blocks
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     399 [ +  - ][ +  - ]:         25 :     GET_DIM( temp_dim, "num_elem", numberElements_loading );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     400 [ +  - ][ +  + ]:         25 :     GET_DIM( temp_dim, "num_node_sets", numberNodeSets_loading );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     401 [ +  - ][ +  + ]:         25 :     GET_DIM( temp_dim, "num_side_sets", numberSideSets_loading );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     402 [ +  - ][ +  - ]:         25 :     GET_DIM( temp_dim, "len_string", max_str_length );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     403 [ +  - ][ +  - ]:         25 :     GET_DIM( temp_dim, "len_line", max_line_length );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     404                 :            : 
     405                 :            :     // Title; why are we even bothering if we're not going to keep it???
     406         [ +  - ]:         25 :     fail = nc_inq_att( ncFile, NC_GLOBAL, "title", &att_type, &att_len );
     407 [ -  + ][ #  # ]:         25 :     if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting title attribute" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     408 [ -  + ][ #  # ]:         25 :     if( att_type != NC_CHAR ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: title didn't have type char" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     409         [ +  - ]:         25 :     char* title = new char[att_len + 1];
     410         [ +  - ]:         25 :     fail        = nc_get_att_text( ncFile, NC_GLOBAL, "title", title );
     411         [ -  + ]:         25 :     if( NC_NOERR != fail )
     412                 :            :     {
     413         [ #  # ]:          0 :         delete[] title;
     414 [ #  # ][ #  # ]:          0 :         MB_SET_ERR( MB_FAILURE, "ReadNCDF:: trouble getting title" );
         [ #  # ][ #  # ]
                 [ #  # ]
     415                 :            :     }
     416         [ +  - ]:         25 :     delete[] title;
     417                 :            : 
     418                 :         25 :     return MB_SUCCESS;
     419                 :            : }
     420                 :            : 
     421                 :         25 : ErrorCode ReadNCDF::read_nodes( const Tag* file_id_tag )
     422                 :            : {
     423                 :            :     // Read the nodes into memory
     424                 :            : 
     425         [ -  + ]:         25 :     assert( 0 != ncFile );
     426                 :            : 
     427                 :            :     // Create a sequence to hold the node coordinates
     428                 :            :     // Get the current number of entities and start at the next slot
     429                 :            : 
     430                 :         25 :     EntityHandle node_handle = 0;
     431         [ +  - ]:         25 :     std::vector< double* > arrays;
     432         [ +  - ]:         25 :     readMeshIface->get_node_coords( 3, numberNodes_loading, MB_START_ID, node_handle, arrays );
     433                 :            : 
     434         [ +  - ]:         25 :     vertexOffset = ID_FROM_HANDLE( node_handle ) - MB_START_ID;
     435                 :            : 
     436                 :            :     // Read in the coordinates
     437                 :            :     int fail;
     438                 :         25 :     int coord = 0;
     439         [ +  - ]:         25 :     nc_inq_varid( ncFile, "coord", &coord );
     440                 :            : 
     441                 :            :     // Single var for all coords
     442                 :         25 :     size_t start[2] = { 0, 0 }, count[2] = { 1, static_cast< size_t >( numberNodes_loading ) };
     443         [ +  - ]:         25 :     if( coord )
     444                 :            :     {
     445         [ +  + ]:        100 :         for( int d = 0; d < numberDimensions_loading; ++d )
     446                 :            :         {
     447                 :         75 :             start[0] = d;
     448 [ +  - ][ +  - ]:         75 :             fail     = nc_get_vara_double( ncFile, coord, start, count, arrays[d] );
     449         [ -  + ]:         75 :             if( NC_NOERR != fail )
     450 [ #  # ][ #  # ]:          0 :             { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting " << (char)( 'x' + d ) << " coord array" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     451                 :            :         }
     452                 :            :     }
     453                 :            :     // Var for each coord
     454                 :            :     else
     455                 :            :     {
     456                 :          0 :         char varname[] = "coord ";
     457         [ #  # ]:          0 :         for( int d = 0; d < numberDimensions_loading; ++d )
     458                 :            :         {
     459                 :          0 :             varname[5] = 'x' + (char)d;
     460         [ #  # ]:          0 :             fail       = nc_inq_varid( ncFile, varname, &coord );
     461         [ #  # ]:          0 :             if( NC_NOERR != fail )
     462 [ #  # ][ #  # ]:          0 :             { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting " << (char)( 'x' + d ) << " coord variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     463                 :            : 
     464 [ #  # ][ #  # ]:          0 :             fail = nc_get_vara_double( ncFile, coord, start, &count[1], arrays[d] );
     465         [ #  # ]:          0 :             if( NC_NOERR != fail )
     466 [ #  # ][ #  # ]:          0 :             { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting " << (char)( 'x' + d ) << " coord array" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     467                 :            :         }
     468                 :            :     }
     469                 :            : 
     470                 :            :     // Zero out any coord values that are in database but not in file
     471                 :            :     // (e.g. if MOAB has 3D coords but file is 2D then set Z coords to zero.)
     472         [ -  + ]:         25 :     for( unsigned d = numberDimensions_loading; d < arrays.size(); ++d )
     473 [ #  # ][ #  # ]:          0 :         std::fill( arrays[d], arrays[d] + numberNodes_loading, 0.0 );
                 [ #  # ]
     474                 :            : 
     475         [ -  + ]:         25 :     if( file_id_tag )
     476                 :            :     {
     477         [ #  # ]:          0 :         Range nodes;
     478         [ #  # ]:          0 :         nodes.insert( node_handle, node_handle + numberNodes_loading - 1 );
     479         [ #  # ]:          0 :         readMeshIface->assign_ids( *file_id_tag, nodes, vertexOffset );
     480                 :            :     }
     481                 :            : 
     482                 :         25 :     return MB_SUCCESS;
     483                 :            : }
     484                 :            : 
     485                 :         25 : ErrorCode ReadNCDF::read_block_headers( const int* blocks_to_load, const int num_blocks )
     486                 :            : {
     487                 :            :     // Get the element block ids; keep this in a separate list,
     488                 :            :     // which is not offset by blockIdOffset; this list used later for
     489                 :            :     // reading block connectivity
     490                 :            : 
     491                 :            :     // Get the ids of all the blocks of this file we're reading in
     492         [ +  - ]:         25 :     std::vector< int > block_ids( numberElementBlocks_loading );
     493                 :         25 :     int nc_block_ids = -1;
     494 [ +  - ][ +  - ]:         25 :     GET_1D_INT_VAR( "eb_prop1", nc_block_ids, block_ids );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     495 [ -  + ][ #  # ]:         25 :     if( -1 == nc_block_ids ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting eb_prop1 variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     496                 :            : 
     497                 :         25 :     int exodus_id = 1;
     498                 :            : 
     499                 :            :     // If the active_block_id_list is NULL all blocks are active.
     500 [ -  + ][ #  # ]:         25 :     if( NULL == blocks_to_load || 0 == num_blocks ) { blocks_to_load = &block_ids[0]; }
                 [ +  - ]
     501                 :            : 
     502         [ +  - ]:         50 :     std::vector< int > new_blocks( blocks_to_load, blocks_to_load + numberElementBlocks_loading );
     503                 :            : 
     504                 :         25 :     std::vector< int >::iterator iter, end_iter;
     505                 :         25 :     iter     = block_ids.begin();
     506                 :         25 :     end_iter = block_ids.end();
     507                 :            : 
     508                 :            :     // Read header information and initialize header-type block information
     509                 :            :     int temp_dim;
     510         [ +  - ]:         50 :     std::vector< char > temp_string_storage( max_str_length + 1 );
     511         [ +  - ]:         25 :     char* temp_string = &temp_string_storage[0];
     512                 :         25 :     int block_seq_id  = 1;
     513                 :            : 
     514 [ +  - ][ +  - ]:        135 :     for( ; iter != end_iter; ++iter, block_seq_id++ )
                 [ +  + ]
     515                 :            :     {
     516                 :            :         int num_elements;
     517                 :            : 
     518 [ +  - ][ +  - ]:        110 :         GET_DIMB( temp_dim, temp_string, "num_el_in_blk%d", block_seq_id, num_elements );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     519                 :            : 
     520                 :            :         // Don't read element type string for now, since it's an attrib
     521                 :            :         // on the connectivity
     522                 :            :         // Get the entity type corresponding to this ExoII element type
     523                 :            :         // ExoIIElementType elem_type =
     524                 :            :         // ExoIIUtil::static_element_name_to_type(element_type_string);
     525                 :            : 
     526                 :            :         // Tag each element block(mesh set) with enum for ElementType (SHELL, QUAD4, ....etc)
     527         [ +  - ]:        110 :         ReadBlockData block_data;
     528                 :        110 :         block_data.elemType    = EXOII_MAX_ELEM_TYPE;
     529         [ +  - ]:        110 :         block_data.blockId     = *iter;
     530                 :        110 :         block_data.startExoId  = exodus_id;
     531                 :        110 :         block_data.numElements = num_elements;
     532                 :            : 
     533                 :            :         // If block is in 'blocks_to_load'----load it!
     534 [ +  - ][ +  - ]:        110 :         if( std::find( new_blocks.begin(), new_blocks.end(), *iter ) != new_blocks.end() )
         [ +  - ][ +  - ]
     535                 :        110 :             block_data.reading_in = true;
     536                 :            :         else
     537                 :          0 :             block_data.reading_in = false;
     538                 :            : 
     539         [ +  - ]:        110 :         blocksLoading.push_back( block_data );
     540                 :        110 :         exodus_id += num_elements;
     541                 :        110 :     }
     542                 :            : 
     543                 :         50 :     return MB_SUCCESS;
     544                 :            : }
     545                 :            : 
     546                 :          0 : ErrorCode ReadNCDF::read_face_blocks_headers()
     547                 :            : {
     548                 :            :     // Get the ids of all the blocks of this file we're reading in
     549         [ #  # ]:          0 :     std::vector< int > fblock_ids( numberFaceBlocks_loading );
     550                 :          0 :     int nc_fblock_ids = -1;
     551 [ #  # ][ #  # ]:          0 :     GET_1D_INT_VAR( "fa_prop1", nc_fblock_ids, fblock_ids );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     552 [ #  # ][ #  # ]:          0 :     if( -1 == nc_fblock_ids ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting fa_prop1 variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     553                 :            : 
     554                 :            :     int temp_dim;
     555         [ #  # ]:          0 :     std::vector< char > temp_string_storage( max_str_length + 1 );
     556         [ #  # ]:          0 :     char* temp_string = &temp_string_storage[0];
     557                 :            :     // int block_seq_id = 1;
     558                 :          0 :     int exodus_id = 1;
     559                 :            : 
     560         [ #  # ]:          0 :     for( int i = 1; i <= numberFaceBlocks_loading; i++ )
     561                 :            :     {
     562                 :            :         int num_elements;
     563                 :            : 
     564 [ #  # ][ #  # ]:          0 :         GET_DIMB( temp_dim, temp_string, "num_fa_in_blk%d", i, num_elements );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     565                 :            : 
     566                 :            :         // Don't read element type string for now, since it's an attrib
     567                 :            :         // on the connectivity
     568                 :            :         // Get the entity type corresponding to this ExoII element type
     569                 :            :         // ExoIIElementType elem_type =
     570                 :            :         // ExoIIUtil::static_element_name_to_type(element_type_string);
     571                 :            : 
     572                 :            :         // Tag each element block(mesh set) with enum for ElementType (SHELL, QUAD4, ....etc)
     573                 :            :         ReadFaceBlockData fblock_data;
     574                 :          0 :         fblock_data.faceBlockId = i;
     575                 :          0 :         fblock_data.startExoId  = exodus_id;
     576                 :          0 :         fblock_data.numElements = num_elements;
     577                 :            : 
     578         [ #  # ]:          0 :         faceBlocksLoading.push_back( fblock_data );
     579                 :          0 :         exodus_id += num_elements;
     580                 :            :     }
     581                 :          0 :     return MB_SUCCESS;
     582                 :            : }
     583                 :          0 : ErrorCode ReadNCDF::read_polyhedra_faces()
     584                 :            : {
     585                 :            :     int temp_dim;
     586         [ #  # ]:          0 :     std::vector< char > temp_string_storage( max_str_length + 1 );
     587         [ #  # ]:          0 :     char* temp_string = &temp_string_storage[0];
     588         [ #  # ]:          0 :     nodesInLoadedBlocks.resize( numberNodes_loading + 1 );
     589                 :          0 :     size_t start[1] = { 0 }, count[1];  // one dim arrays only here!
     590                 :          0 :     std::vector< ReadFaceBlockData >::iterator this_it;
     591                 :          0 :     this_it = faceBlocksLoading.begin();
     592                 :            : 
     593                 :          0 :     int fblock_seq_id = 1;
     594         [ #  # ]:          0 :     std::vector< int > dims;
     595                 :            :     int nc_var, fail;
     596                 :            : 
     597 [ #  # ][ #  # ]:          0 :     for( ; this_it != faceBlocksLoading.end(); ++this_it, fblock_seq_id++ )
                 [ #  # ]
     598                 :            :     {
     599                 :            :         int num_fa_in_blk;
     600 [ #  # ][ #  # ]:          0 :         GET_DIMB( temp_dim, temp_string, "num_fa_in_blk%d", fblock_seq_id, num_fa_in_blk );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     601                 :            :         int num_nod_per_fa;
     602 [ #  # ][ #  # ]:          0 :         GET_DIMB( temp_dim, temp_string, "num_nod_per_fa%d", fblock_seq_id, num_nod_per_fa );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     603                 :            :         // Get the ncdf connect variable and the element type
     604                 :          0 :         INS_ID( temp_string, "fbconn%d", fblock_seq_id );
     605 [ #  # ][ #  # ]:          0 :         GET_VAR( temp_string, nc_var, dims );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     606         [ #  # ]:          0 :         std::vector< int > fbconn;
     607         [ #  # ]:          0 :         fbconn.resize( num_nod_per_fa );
     608                 :          0 :         count[0] = num_nod_per_fa;
     609                 :            : 
     610 [ #  # ][ #  # ]:          0 :         fail = nc_get_vara_int( ncFile, nc_var, start, count, &fbconn[0] );
     611 [ #  # ][ #  # ]:          0 :         if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting face polyhedra connectivity " ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     612 [ #  # ][ #  # ]:          0 :         std::vector< int > fbepecnt;
     613         [ #  # ]:          0 :         fbepecnt.resize( num_fa_in_blk );
     614                 :          0 :         INS_ID( temp_string, "fbepecnt%d", fblock_seq_id );
     615 [ #  # ][ #  # ]:          0 :         GET_VAR( temp_string, nc_var, dims );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     616                 :          0 :         count[0] = num_fa_in_blk;
     617 [ #  # ][ #  # ]:          0 :         fail     = nc_get_vara_int( ncFile, nc_var, start, count, &fbepecnt[0] );
     618 [ #  # ][ #  # ]:          0 :         if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting face polyhedra connectivity " ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     619                 :            :         // now we can create some polygons
     620 [ #  # ][ #  # ]:          0 :         std::vector< EntityHandle > polyConn;
     621                 :          0 :         int ix = 0;
     622 [ #  # ][ #  # ]:          0 :         for( int i = 0; i < num_fa_in_blk; i++ )
     623                 :            :         {
     624 [ #  # ][ #  # ]:          0 :             polyConn.resize( fbepecnt[i] );
     625 [ #  # ][ #  # ]:          0 :             for( int j = 0; j < fbepecnt[i]; j++ )
     626                 :            :             {
     627 [ #  # ][ #  # ]:          0 :                 nodesInLoadedBlocks[fbconn[ix]] = 1;
     628 [ #  # ][ #  # ]:          0 :                 polyConn[j]                     = vertexOffset + fbconn[ix++];
     629                 :            :             }
     630                 :            :             EntityHandle newp;
     631                 :            :             /*
     632                 :            :              *  ErrorCode create_element(const EntityType type,
     633                 :            :                                          const EntityHandle *connectivity,
     634                 :            :                                          const int num_vertices,
     635                 :            :                                          EntityHandle &element_handle)
     636                 :            :              */
     637 [ #  # ][ #  # ]:          0 :             if( mdbImpl->create_element( MBPOLYGON, &polyConn[0], fbepecnt[i], newp ) != MB_SUCCESS ) return MB_FAILURE;
         [ #  # ][ #  # ]
     638                 :            : 
     639                 :            :             // add the element in order
     640         [ #  # ]:          0 :             polyfaces.push_back( newp );
     641                 :            :         }
     642                 :          0 :     }
     643                 :          0 :     return MB_SUCCESS;
     644                 :            : }
     645                 :            : 
     646                 :         25 : ErrorCode ReadNCDF::read_elements( const Tag* file_id_tag )
     647                 :            : {
     648                 :            :     // Read in elements
     649                 :            : 
     650                 :         25 :     int result = 0;
     651                 :            : 
     652                 :            :     // Initialize the nodeInLoadedBlocks vector
     653         [ +  - ]:         25 :     if( nodesInLoadedBlocks.size() < ( size_t )( numberNodes_loading + 1 ) )
     654         [ +  - ]:         25 :         nodesInLoadedBlocks.resize( numberNodes_loading + 1 );  // this could be repeated?
     655         [ +  - ]:         25 :     memset( &nodesInLoadedBlocks[0], 0, ( numberNodes_loading + 1 ) * sizeof( char ) );
     656                 :            : 
     657                 :         25 :     std::vector< ReadBlockData >::iterator this_it;
     658                 :         25 :     this_it = blocksLoading.begin();
     659                 :            : 
     660                 :            :     int temp_dim;
     661         [ +  - ]:         25 :     std::vector< char > temp_string_storage( max_str_length + 1 );
     662         [ +  - ]:         25 :     char* temp_string = &temp_string_storage[0];
     663                 :            : 
     664                 :            :     int nc_var;
     665                 :         25 :     int block_seq_id = 1;
     666         [ +  - ]:         50 :     std::vector< int > dims;
     667                 :         25 :     size_t start[2] = { 0, 0 }, count[2];
     668                 :            : 
     669 [ +  - ][ +  - ]:        135 :     for( ; this_it != blocksLoading.end(); ++this_it, block_seq_id++ )
                 [ +  + ]
     670                 :            :     {
     671                 :            :         // If this block isn't to be read in --- continue
     672 [ +  - ][ -  + ]:        110 :         if( !( *this_it ).reading_in ) continue;
     673                 :            : 
     674                 :            :         // Get some information about this block
     675         [ +  - ]:        110 :         int block_id       = ( *this_it ).blockId;
     676                 :        110 :         EntityHandle* conn = 0;
     677                 :            : 
     678                 :            :         // Get the ncdf connect variable and the element type
     679                 :        110 :         INS_ID( temp_string, "connect%d", block_seq_id );
     680 [ +  - ][ +  - ]:        110 :         GET_VAR( temp_string, nc_var, dims );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     681 [ +  - ][ -  + ]:        110 :         if( -1 == nc_var || 0 == nc_var )
     682                 :            :         {  // try other var, for polyhedra blocks
     683                 :            :             // it could be polyhedra block, defined by fbconn and NFACED attribute
     684                 :          0 :             INS_ID( temp_string, "facconn%d", block_seq_id );
     685 [ #  # ][ #  # ]:          0 :             GET_VAR( temp_string, nc_var, dims );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     686                 :            : 
     687 [ #  # ][ #  # ]:          0 :             if( -1 == nc_var || 0 == nc_var )
     688 [ #  # ][ #  # ]:          0 :             { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting connec or faccon variable" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     689                 :            :         }
     690                 :            :         nc_type att_type;
     691                 :            :         size_t att_len;
     692         [ +  - ]:        110 :         int fail = nc_inq_att( ncFile, nc_var, "elem_type", &att_type, &att_len );
     693 [ -  + ][ #  # ]:        110 :         if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting elem type attribute" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     694         [ +  - ]:        110 :         std::vector< char > dum_str( att_len + 1 );
     695 [ +  - ][ +  - ]:        110 :         fail = nc_get_att_text( ncFile, nc_var, "elem_type", &dum_str[0] );
     696 [ -  + ][ #  # ]:        110 :         if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting elem type" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     697 [ +  - ][ +  - ]:        110 :         ExoIIElementType elem_type = ExoIIUtil::static_element_name_to_type( &dum_str[0] );
     698         [ +  - ]:        110 :         ( *this_it ).elemType      = elem_type;
     699                 :            : 
     700         [ +  - ]:        110 :         int verts_per_element    = ExoIIUtil::VerticesPerElement[( *this_it ).elemType];
     701         [ +  - ]:        110 :         int number_nodes         = ( *this_it ).numElements * verts_per_element;
     702         [ +  - ]:        110 :         const EntityType mb_type = ExoIIUtil::ExoIIElementMBEntity[( *this_it ).elemType];
     703                 :            : 
     704         [ -  + ]:        110 :         if( mb_type == MBPOLYGON )
     705                 :            :         {
     706                 :            :             // need to read another variable, num_nod_per_el, and
     707                 :            :             int num_nodes_poly_conn;
     708 [ #  # ][ #  # ]:          0 :             GET_DIMB( temp_dim, temp_string, "num_nod_per_el%d", block_seq_id, num_nodes_poly_conn );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     709                 :            :             // read the connec1 array, which is of dimensions num_nodes_poly_conn (only one )
     710         [ #  # ]:          0 :             std::vector< int > connec;
     711         [ #  # ]:          0 :             connec.resize( num_nodes_poly_conn );
     712                 :          0 :             count[0] = num_nodes_poly_conn;
     713                 :            : 
     714 [ #  # ][ #  # ]:          0 :             fail = nc_get_vara_int( ncFile, nc_var, start, count, &connec[0] );
     715 [ #  # ][ #  # ]:          0 :             if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting polygon connectivity " ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     716                 :            :             // ebepecnt1
     717 [ #  # ][ #  # ]:          0 :             std::vector< int > ebec;
     718 [ #  # ][ #  # ]:          0 :             ebec.resize( this_it->numElements );
     719                 :            :             // Get the ncdf connect variable and the element type
     720                 :          0 :             INS_ID( temp_string, "ebepecnt%d", block_seq_id );
     721 [ #  # ][ #  # ]:          0 :             GET_VAR( temp_string, nc_var, dims );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     722         [ #  # ]:          0 :             count[0] = this_it->numElements;
     723 [ #  # ][ #  # ]:          0 :             fail     = nc_get_vara_int( ncFile, nc_var, start, count, &ebec[0] );
     724 [ #  # ][ #  # ]:          0 :             if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting polygon nodes per elem " ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     725                 :            :             EntityHandle ms_handle;
     726 [ #  # ][ #  # ]:          0 :             if( mdbImpl->create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, ms_handle ) != MB_SUCCESS )
     727                 :          0 :                 return MB_FAILURE;
     728                 :            :             // create polygons one by one, and put them in the list
     729                 :            :             // also need to read the number of nodes for each polygon, then create
     730 [ #  # ][ #  # ]:          0 :             std::vector< EntityHandle > polyConn;
     731                 :          0 :             int ix = 0;
     732 [ #  # ][ #  # ]:          0 :             for( int i = 0; i < this_it->numElements; i++ )
     733                 :            :             {
     734 [ #  # ][ #  # ]:          0 :                 polyConn.resize( ebec[i] );
     735 [ #  # ][ #  # ]:          0 :                 for( int j = 0; j < ebec[i]; j++ )
     736                 :            :                 {
     737 [ #  # ][ #  # ]:          0 :                     nodesInLoadedBlocks[connec[ix]] = 1;
     738 [ #  # ][ #  # ]:          0 :                     polyConn[j]                     = vertexOffset + connec[ix++];
     739                 :            :                 }
     740                 :            :                 EntityHandle newp;
     741                 :            :                 /*
     742                 :            :                  *  ErrorCode create_element(const EntityType type,
     743                 :            :                                              const EntityHandle *connectivity,
     744                 :            :                                              const int num_vertices,
     745                 :            :                                              EntityHandle &element_handle)
     746                 :            :                  */
     747 [ #  # ][ #  # ]:          0 :                 if( mdbImpl->create_element( MBPOLYGON, &polyConn[0], ebec[i], newp ) != MB_SUCCESS ) return MB_FAILURE;
         [ #  # ][ #  # ]
     748                 :            : 
     749                 :            :                 // add the element in order
     750 [ #  # ][ #  # ]:          0 :                 this_it->polys.push_back( newp );
     751 [ #  # ][ #  # ]:          0 :                 if( mdbImpl->add_entities( ms_handle, &newp, 1 ) != MB_SUCCESS ) return MB_FAILURE;
     752                 :            :             }
     753                 :            :             // Set the block id with an offset
     754 [ #  # ][ #  # ]:          0 :             if( mdbImpl->tag_set_data( mMaterialSetTag, &ms_handle, 1, &block_id ) != MB_SUCCESS ) return MB_FAILURE;
     755 [ #  # ][ #  # ]:          0 :             if( mdbImpl->tag_set_data( mGlobalIdTag, &ms_handle, 1, &block_id ) != MB_SUCCESS ) return MB_FAILURE;
                 [ #  # ]
     756                 :            :         }
     757         [ -  + ]:        110 :         else if( mb_type == MBPOLYHEDRON )
     758                 :            :         {
     759                 :            :             // need to read another variable, num_fac_per_el
     760                 :            :             int num_fac_per_el;
     761 [ #  # ][ #  # ]:          0 :             GET_DIMB( temp_dim, temp_string, "num_fac_per_el%d", block_seq_id, num_fac_per_el );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     762                 :            :             // read the fbconn array, which is of dimensions num_nod_per_fa (only one dimension)
     763         [ #  # ]:          0 :             std::vector< int > facconn;
     764         [ #  # ]:          0 :             facconn.resize( num_fac_per_el );
     765                 :          0 :             count[0] = num_fac_per_el;
     766                 :            : 
     767 [ #  # ][ #  # ]:          0 :             fail = nc_get_vara_int( ncFile, nc_var, start, count, &facconn[0] );
     768 [ #  # ][ #  # ]:          0 :             if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting polygon connectivity " ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     769                 :            :             // ebepecnt1
     770 [ #  # ][ #  # ]:          0 :             std::vector< int > ebepecnt;
     771 [ #  # ][ #  # ]:          0 :             ebepecnt.resize( this_it->numElements );
     772                 :            :             // Get the ncdf connect variable and the element type
     773                 :          0 :             INS_ID( temp_string, "ebepecnt%d", block_seq_id );
     774 [ #  # ][ #  # ]:          0 :             GET_VAR( temp_string, nc_var, dims );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     775         [ #  # ]:          0 :             count[0] = this_it->numElements;
     776 [ #  # ][ #  # ]:          0 :             fail     = nc_get_vara_int( ncFile, nc_var, start, count, &ebepecnt[0] );
     777 [ #  # ][ #  # ]:          0 :             if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting polygon nodes per elem " ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     778                 :            :             EntityHandle ms_handle;
     779 [ #  # ][ #  # ]:          0 :             if( mdbImpl->create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, ms_handle ) != MB_SUCCESS )
     780                 :          0 :                 return MB_FAILURE;
     781                 :            :             // create polygons one by one, and put them in the list
     782                 :            :             // also need to read the number of nodes for each polygon, then create
     783 [ #  # ][ #  # ]:          0 :             std::vector< EntityHandle > polyConn;
     784                 :          0 :             int ix = 0;
     785 [ #  # ][ #  # ]:          0 :             for( int i = 0; i < this_it->numElements; i++ )
     786                 :            :             {
     787 [ #  # ][ #  # ]:          0 :                 polyConn.resize( ebepecnt[i] );
     788 [ #  # ][ #  # ]:          0 :                 for( int j = 0; j < ebepecnt[i]; j++ )
     789                 :            :                 {
     790 [ #  # ][ #  # ]:          0 :                     polyConn[j] = polyfaces[facconn[ix++] - 1];
                 [ #  # ]
     791                 :            :                 }
     792                 :            :                 EntityHandle newp;
     793                 :            :                 /*
     794                 :            :                  *  ErrorCode create_element(const EntityType type,
     795                 :            :                                              const EntityHandle *connectivity,
     796                 :            :                                              const int num_vertices,
     797                 :            :                                              EntityHandle &element_handle)
     798                 :            :                  */
     799 [ #  # ][ #  # ]:          0 :                 if( mdbImpl->create_element( MBPOLYHEDRON, &polyConn[0], ebepecnt[i], newp ) != MB_SUCCESS )
         [ #  # ][ #  # ]
     800                 :          0 :                     return MB_FAILURE;
     801                 :            : 
     802                 :            :                 // add the element in order
     803 [ #  # ][ #  # ]:          0 :                 this_it->polys.push_back( newp );
     804 [ #  # ][ #  # ]:          0 :                 if( mdbImpl->add_entities( ms_handle, &newp, 1 ) != MB_SUCCESS ) return MB_FAILURE;
     805                 :            :             }
     806                 :            :             // Set the block id with an offset
     807 [ #  # ][ #  # ]:          0 :             if( mdbImpl->tag_set_data( mMaterialSetTag, &ms_handle, 1, &block_id ) != MB_SUCCESS ) return MB_FAILURE;
     808 [ #  # ][ #  # ]:          0 :             if( mdbImpl->tag_set_data( mGlobalIdTag, &ms_handle, 1, &block_id ) != MB_SUCCESS ) return MB_FAILURE;
                 [ #  # ]
     809                 :            :         }
     810                 :            :         else  // this is regular
     811                 :            :         {
     812                 :            :             // Allocate an array to read in connectivity data
     813 [ +  - ][ +  - ]:        110 :             readMeshIface->get_element_connect( this_it->numElements, verts_per_element, mb_type, this_it->startExoId,
     814 [ +  - ][ +  - ]:        220 :                                                 this_it->startMBId, conn );
     815                 :            : 
     816                 :            :             // Create a range for this sequence of elements
     817                 :            :             EntityHandle start_range, end_range;
     818         [ +  - ]:        110 :             start_range = ( *this_it ).startMBId;
     819         [ +  - ]:        110 :             end_range   = start_range + ( *this_it ).numElements - 1;
     820                 :            : 
     821         [ +  - ]:        110 :             Range new_range( start_range, end_range );
     822                 :            :             // Range<EntityHandle> new_range((*this_it).startMBId,
     823                 :            :             //                              (*this_it).startMBId + (*this_it).numElements - 1);
     824                 :            : 
     825                 :            :             // Create a MBSet for this block and set the material tag
     826                 :            : 
     827                 :            :             EntityHandle ms_handle;
     828 [ +  - ][ -  + ]:        110 :             if( mdbImpl->create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, ms_handle ) != MB_SUCCESS )
     829                 :          0 :                 return MB_FAILURE;
     830                 :            : 
     831 [ +  - ][ -  + ]:        110 :             if( mdbImpl->add_entities( ms_handle, new_range ) != MB_SUCCESS ) return MB_FAILURE;
     832                 :            : 
     833                 :            :             int mid_nodes[4];
     834         [ +  - ]:        110 :             CN::HasMidNodes( mb_type, verts_per_element, mid_nodes );
     835 [ +  - ][ -  + ]:        110 :             if( mdbImpl->tag_set_data( mHasMidNodesTag, &ms_handle, 1, mid_nodes ) != MB_SUCCESS ) return MB_FAILURE;
     836                 :            : 
     837                 :            :             // Just a check because the following code won't work if this case fails
     838                 :            :             assert( sizeof( EntityHandle ) >= sizeof( int ) );
     839                 :            : 
     840                 :            :             // tmp_ptr is of type int* and points at the same place as conn
     841                 :        110 :             int* tmp_ptr = reinterpret_cast< int* >( conn );
     842                 :            : 
     843                 :            :             // Read the connectivity into that memory,  this will take only part of the array
     844                 :            :             // 1/2 if sizeof(EntityHandle) == 64 bits.
     845         [ +  - ]:        110 :             count[0] = this_it->numElements;
     846                 :        110 :             count[1] = verts_per_element;
     847         [ +  - ]:        110 :             fail     = nc_get_vara_int( ncFile, nc_var, start, count, tmp_ptr );
     848 [ -  + ][ #  # ]:        110 :             if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting connectivity" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     849                 :            : 
     850                 :            :             // Convert from exodus indices to vertex handles.
     851                 :            :             // Iterate backwards in case handles are larger than ints.
     852         [ +  + ]:    2063806 :             for( int i = number_nodes - 1; i >= 0; --i )
     853                 :            :             {
     854         [ -  + ]:    2063696 :                 if( (unsigned)tmp_ptr[i] >= nodesInLoadedBlocks.size() )
     855 [ #  # ][ #  # ]:          0 :                 { MB_SET_ERR( MB_FAILURE, "Invalid node ID in block connectivity" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     856         [ +  - ]:    2063696 :                 nodesInLoadedBlocks[tmp_ptr[i]] = 1;
     857                 :    2063696 :                 conn[i]                         = static_cast< EntityHandle >( tmp_ptr[i] ) + vertexOffset;
     858                 :            :             }
     859                 :            : 
     860                 :            :             // Adjust connectivity order if necessary
     861                 :        110 :             const int* reorder = exodus_elem_order_map[mb_type][verts_per_element];
     862 [ +  + ][ +  - ]:        110 :             if( reorder ) ReadUtilIface::reorder( reorder, conn, this_it->numElements, verts_per_element );
                 [ +  - ]
     863                 :            : 
     864 [ +  - ][ +  - ]:        110 :             readMeshIface->update_adjacencies( ( *this_it ).startMBId, ( *this_it ).numElements,
     865 [ +  - ][ +  - ]:        220 :                                                ExoIIUtil::VerticesPerElement[( *this_it ).elemType], conn );
     866                 :            : 
     867         [ -  + ]:        110 :             if( result == -1 )
     868 [ #  # ][ #  # ]:          0 :             { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: error getting element connectivity for block " << block_id ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     869                 :            : 
     870                 :            :             // Set the block id with an offset
     871 [ +  - ][ -  + ]:        110 :             if( mdbImpl->tag_set_data( mMaterialSetTag, &ms_handle, 1, &block_id ) != MB_SUCCESS ) return MB_FAILURE;
     872 [ +  - ][ -  + ]:        110 :             if( mdbImpl->tag_set_data( mGlobalIdTag, &ms_handle, 1, &block_id ) != MB_SUCCESS ) return MB_FAILURE;
     873                 :            : 
     874         [ -  + ]:        110 :             if( file_id_tag )
     875                 :            :             {
     876         [ #  # ]:          0 :                 Range range;
     877 [ #  # ][ #  # ]:          0 :                 range.insert( this_it->startMBId, this_it->startMBId + this_it->numElements - 1 );
         [ #  # ][ #  # ]
     878 [ #  # ][ #  # ]:        110 :                 readMeshIface->assign_ids( *file_id_tag, range, this_it->startExoId );
                 [ +  - ]
     879         [ +  - ]:        110 :             }
     880                 :            :         }  // end regular block (not polygon)
     881                 :        110 :     }
     882                 :            : 
     883                 :         50 :     return MB_SUCCESS;
     884                 :            : }
     885                 :            : 
     886                 :         25 : ErrorCode ReadNCDF::read_global_ids()
     887                 :            : {
     888                 :            :     // Read in the map from the exodus file
     889 [ +  - ][ +  - ]:         25 :     std::vector< int > ids( std::max( numberElements_loading, numberNodes_loading ) );
     890                 :            : 
     891                 :         25 :     int varid = -1;
     892 [ +  - ][ +  - ]:         25 :     GET_1D_INT_VAR( "elem_map", varid, ids );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     893         [ +  - ]:         25 :     if( -1 != varid )
     894                 :            :     {
     895                 :         25 :         std::vector< ReadBlockData >::iterator iter;
     896                 :         25 :         int id_pos = 0;
     897 [ +  - ][ +  - ]:        135 :         for( iter = blocksLoading.begin(); iter != blocksLoading.end(); ++iter )
                 [ +  + ]
     898                 :            :         {
     899 [ +  - ][ +  - ]:        110 :             if( iter->reading_in )
     900                 :            :             {
     901 [ +  - ][ +  - ]:        110 :                 if( iter->elemType != EXOII_POLYGON && iter->elemType != EXOII_POLYHEDRON )
         [ +  - ][ +  - ]
                 [ +  - ]
     902                 :            :                 {
     903 [ +  - ][ +  - ]:        110 :                     if( iter->startMBId != 0 )
     904                 :            :                     {
     905 [ +  - ][ +  - ]:        110 :                         Range range( iter->startMBId, iter->startMBId + iter->numElements - 1 );
         [ +  - ][ +  - ]
     906 [ +  - ][ +  - ]:        110 :                         ErrorCode error = mdbImpl->tag_set_data( mGlobalIdTag, range, &ids[id_pos] );
     907         [ -  + ]:        110 :                         if( error != MB_SUCCESS ) return error;
     908 [ +  - ][ +  - ]:        110 :                         id_pos += iter->numElements;
     909                 :            :                     }
     910                 :            :                     else
     911                 :        110 :                         return MB_FAILURE;
     912                 :            :                 }
     913                 :            :                 else  // polygons or polyhedrons; use id from elements
     914                 :            :                 {
     915 [ #  # ][ #  # ]:        110 :                     for( std::vector< EntityHandle >::iterator eit = iter->polys.begin(); eit != iter->polys.end();
         [ #  # ][ #  # ]
                 [ #  # ]
     916                 :            :                          eit++, id_pos++ )
     917                 :            :                     {
     918         [ #  # ]:          0 :                         EntityHandle peh = *eit;
     919 [ #  # ][ #  # ]:          0 :                         if( mdbImpl->tag_set_data( mGlobalIdTag, &peh, 1, &ids[id_pos] ) != MB_SUCCESS )
                 [ #  # ]
     920                 :          0 :                             return MB_FAILURE;
     921                 :            :                     }
     922                 :            :                 }
     923                 :            :             }
     924                 :            :         }
     925                 :            :     }
     926                 :            : 
     927                 :            :     // Read in node map next
     928                 :         25 :     varid = -1;
     929 [ +  - ][ +  + ]:         25 :     GET_1D_INT_VAR( "node_num_map", varid, ids );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  + ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     930         [ +  + ]:         25 :     if( -1 != varid )
     931                 :            :     {
     932         [ +  - ]:         22 :         Range range( MB_START_ID + vertexOffset, MB_START_ID + vertexOffset + numberNodes_loading - 1 );
     933 [ +  - ][ +  - ]:         22 :         ErrorCode error = mdbImpl->tag_set_data( mGlobalIdTag, range, &ids[0] );
     934 [ -  + ][ #  # ]:         22 :         if( MB_SUCCESS != error ) MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem setting node global ids" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ +  - ]
     935                 :            :     }
     936                 :            : 
     937                 :         25 :     return MB_SUCCESS;
     938                 :            : }
     939                 :            : 
     940                 :         25 : ErrorCode ReadNCDF::read_nodesets()
     941                 :            : {
     942                 :            :     // Read in the nodesets for the model
     943                 :            : 
     944         [ +  + ]:         25 :     if( 0 == numberNodeSets_loading ) return MB_SUCCESS;
     945         [ +  - ]:         13 :     std::vector< int > id_array( numberNodeSets_loading );
     946                 :            : 
     947                 :            :     // Read in the nodeset ids
     948                 :            :     int nc_var;
     949 [ +  - ][ +  - ]:         13 :     GET_1D_INT_VAR( "ns_prop1", nc_var, id_array );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     950 [ -  + ][ #  # ]:         13 :     if( -1 == nc_var ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting ns_prop1 variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     951                 :            : 
     952                 :            :     // Use a vector of ints to read node handles
     953         [ +  - ]:         26 :     std::vector< int > node_handles;
     954                 :            : 
     955                 :            :     int i;
     956         [ +  - ]:         26 :     std::vector< char > temp_string_storage( max_str_length + 1 );
     957         [ +  - ]:         13 :     char* temp_string = &temp_string_storage[0];
     958                 :            :     int temp_dim;
     959         [ +  + ]:         50 :     for( i = 0; i < numberNodeSets_loading; i++ )
     960                 :            :     {
     961                 :            :         // Get nodeset parameters
     962                 :            :         int number_nodes_in_set;
     963                 :            :         int number_dist_factors_in_set;
     964                 :            : 
     965 [ +  - ][ +  - ]:         37 :         GET_DIMB( temp_dim, temp_string, "num_nod_ns%d", i + 1, number_nodes_in_set );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     966 [ +  - ][ -  + ]:         37 :         GET_DIMB( temp_dim, temp_string, "num_df_ns%d", i + 1, number_dist_factors_in_set );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     967                 :            : 
     968                 :            :         // Need to new a vector to store dist. factors
     969                 :            :         // This vector * gets stored as a tag on the sideset meshset
     970         [ +  - ]:         37 :         std::vector< double > temp_dist_factor_vector( number_nodes_in_set );
     971         [ -  + ]:         37 :         if( number_dist_factors_in_set != 0 )
     972                 :            :         {
     973                 :          0 :             INS_ID( temp_string, "dist_fact_ns%d", i + 1 );
     974 [ #  # ][ #  # ]:          0 :             GET_1D_DBL_VAR( temp_string, temp_dim, temp_dist_factor_vector );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     975 [ #  # ][ #  # ]:          0 :             if( -1 == temp_dim ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting dist fact variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     976                 :            :         }
     977                 :            : 
     978                 :            :         // Size new arrays and get ids and distribution factors
     979         [ +  + ]:         37 :         if( node_handles.size() < (unsigned int)number_nodes_in_set )
     980                 :            :         {
     981         [ +  - ]:         13 :             node_handles.reserve( number_nodes_in_set );
     982         [ +  - ]:         13 :             node_handles.resize( number_nodes_in_set );
     983                 :            :         }
     984                 :            : 
     985                 :         37 :         INS_ID( temp_string, "node_ns%d", i + 1 );
     986                 :         37 :         int temp_var = -1;
     987 [ +  - ][ +  - ]:         37 :         GET_1D_INT_VAR( temp_string, temp_var, node_handles );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     988 [ -  + ][ #  # ]:         37 :         if( -1 == temp_var ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting nodeset node variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     989                 :            : 
     990                 :            :         // Maybe there is already a nodesets meshset here we can append to
     991         [ +  - ]:         74 :         Range child_meshsets;
              [ +  -  - ]
     992 [ +  - ][ -  + ]:         37 :         if( mdbImpl->get_entities_by_handle( 0, child_meshsets ) != MB_SUCCESS ) return MB_FAILURE;
     993                 :            : 
     994 [ +  - ][ +  - ]:         37 :         child_meshsets = subtract( child_meshsets, initRange );
     995                 :            : 
     996 [ +  - ][ +  - ]:         37 :         Range::iterator iter, end_iter;
     997         [ +  - ]:         37 :         iter     = child_meshsets.begin();
     998         [ +  - ]:         37 :         end_iter = child_meshsets.end();
     999                 :            : 
    1000                 :         37 :         EntityHandle ns_handle = 0;
    1001 [ +  - ][ +  - ]:       4597 :         for( ; iter != end_iter; ++iter )
                 [ +  + ]
    1002                 :            :         {
    1003                 :            :             int nodeset_id;
    1004 [ +  - ][ +  - ]:       4560 :             if( mdbImpl->tag_get_data( mDirichletSetTag, &( *iter ), 1, &nodeset_id ) != MB_SUCCESS ) continue;
                 [ -  + ]
    1005                 :            : 
    1006 [ +  - ][ -  + ]:       4560 :             if( id_array[i] == nodeset_id )
    1007                 :            :             {
    1008                 :            :                 // Found the meshset
    1009         [ #  # ]:          0 :                 ns_handle = *iter;
    1010                 :       4560 :                 break;
    1011                 :            :             }
    1012                 :            :         }
    1013                 :            : 
    1014         [ +  - ]:         74 :         std::vector< EntityHandle > nodes_of_nodeset;
              [ +  -  - ]
    1015         [ -  + ]:         37 :         if( ns_handle )
    1016 [ #  # ][ #  # ]:          0 :             if( mdbImpl->get_entities_by_handle( ns_handle, nodes_of_nodeset, true ) != MB_SUCCESS ) return MB_FAILURE;
    1017                 :            : 
    1018                 :            :         // Make these into entity handles
    1019                 :            :         // TODO: could we have read it into EntityHandle sized array in the first place?
    1020                 :            :         int j, temp;
    1021         [ +  - ]:         74 :         std::vector< EntityHandle > nodes;
              [ +  -  - ]
    1022         [ +  - ]:         74 :         std::vector< double > dist_factor_vector;
              [ +  -  - ]
    1023         [ +  + ]:        481 :         for( j = 0; j < number_nodes_in_set; j++ )
    1024                 :            :         {
    1025                 :            :             // See if this node is one we're currently reading in
    1026 [ +  - ][ +  - ]:        444 :             if( nodesInLoadedBlocks[node_handles[j]] == 1 )
                 [ +  - ]
    1027                 :            :             {
    1028                 :            :                 // Make sure that it already isn't in a nodeset
    1029 [ +  - ][ +  - ]:        444 :                 unsigned int node_id = CREATE_HANDLE( MBVERTEX, node_handles[j] + vertexOffset, temp );
    1030 [ -  + ][ #  # ]:        888 :                 if( !ns_handle ||
                 [ +  - ]
    1031 [ #  # ][ #  # ]:        444 :                     std::find( nodes_of_nodeset.begin(), nodes_of_nodeset.end(), node_id ) == nodes_of_nodeset.end() )
         [ -  + ][ +  - ]
           [ #  #  #  # ]
    1032                 :            :                 {
    1033         [ +  - ]:        444 :                     nodes.push_back( node_id );
    1034                 :            : 
    1035 [ -  + ][ #  # ]:        444 :                     if( number_dist_factors_in_set != 0 ) dist_factor_vector.push_back( temp_dist_factor_vector[j] );
                 [ #  # ]
    1036                 :            :                 }
    1037                 :            :             }
    1038                 :            :         }
    1039                 :            : 
    1040                 :            :         // No nodes to add
    1041         [ -  + ]:         37 :         if( nodes.empty() ) continue;
    1042                 :            : 
    1043                 :            :         // If there was no meshset found --> create one
    1044         [ +  - ]:         37 :         if( ns_handle == 0 )
    1045                 :            :         {
    1046 [ +  - ][ -  + ]:         37 :             if( mdbImpl->create_meshset( MESHSET_ORDERED | MESHSET_TRACK_OWNER, ns_handle ) != MB_SUCCESS )
    1047                 :          0 :                 return MB_FAILURE;
    1048                 :            : 
    1049                 :            :             // Set a tag signifying dirichlet bc
    1050                 :            :             // TODO: create this tag another way
    1051                 :            : 
    1052         [ +  - ]:         37 :             int nodeset_id = id_array[i];
    1053 [ +  - ][ -  + ]:         37 :             if( mdbImpl->tag_set_data( mDirichletSetTag, &ns_handle, 1, &nodeset_id ) != MB_SUCCESS ) return MB_FAILURE;
    1054 [ +  - ][ -  + ]:         37 :             if( mdbImpl->tag_set_data( mGlobalIdTag, &ns_handle, 1, &nodeset_id ) != MB_SUCCESS ) return MB_FAILURE;
    1055                 :            : 
    1056         [ -  + ]:         37 :             if( !dist_factor_vector.empty() )
    1057                 :            :             {
    1058                 :          0 :                 int size         = dist_factor_vector.size();
    1059         [ #  # ]:          0 :                 const void* data = &dist_factor_vector[0];
    1060 [ #  # ][ #  # ]:          0 :                 if( mdbImpl->tag_set_by_ptr( mDistFactorTag, &ns_handle, 1, &data, &size ) != MB_SUCCESS )
    1061                 :         37 :                     return MB_FAILURE;
    1062                 :            :             }
    1063                 :            :         }
    1064         [ #  # ]:          0 :         else if( !dist_factor_vector.empty() )
    1065                 :            :         {
    1066                 :            :             // Append dist factors to vector
    1067                 :          0 :             const void* ptr = 0;
    1068                 :          0 :             int size        = 0;
    1069 [ #  # ][ #  # ]:          0 :             if( mdbImpl->tag_get_by_ptr( mDistFactorTag, &ns_handle, 1, &ptr, &size ) != MB_SUCCESS ) return MB_FAILURE;
    1070                 :            : 
    1071                 :          0 :             const double* data = reinterpret_cast< const double* >( ptr );
    1072         [ #  # ]:          0 :             dist_factor_vector.reserve( dist_factor_vector.size() + size );
    1073 [ #  # ][ #  # ]:          0 :             std::copy( data, data + size, std::back_inserter( dist_factor_vector ) );
    1074                 :          0 :             size = dist_factor_vector.size();
    1075         [ #  # ]:          0 :             ptr  = &dist_factor_vector[0];
    1076 [ #  # ][ #  # ]:          0 :             if( mdbImpl->tag_set_by_ptr( mDistFactorTag, &ns_handle, 1, &ptr, &size ) != MB_SUCCESS ) return MB_FAILURE;
    1077                 :            :         }
    1078                 :            : 
    1079                 :            :         // Add the nodes to the meshset
    1080 [ +  - ][ +  - ]:         37 :         if( mdbImpl->add_entities( ns_handle, &nodes[0], nodes.size() ) != MB_SUCCESS ) return MB_FAILURE;
                 [ -  + ]
              [ +  -  - ]
    1081                 :         37 :     }
    1082                 :            : 
    1083                 :         38 :     return MB_SUCCESS;
    1084                 :            : }
    1085                 :            : 
    1086                 :         25 : ErrorCode ReadNCDF::read_sidesets()
    1087                 :            : {
    1088                 :            :     // Uhhh if you read the same file (previously_read==true) then blow away the
    1089                 :            :     // sidesets pertaining to this file?  How do you do that? If you read a
    1090                 :            :     // new file make sure all the offsets are correct.
    1091                 :            : 
    1092                 :            :     // If not loading any sidesets -- exit
    1093         [ +  + ]:         25 :     if( 0 == numberSideSets_loading ) return MB_SUCCESS;
    1094                 :            : 
    1095                 :            :     // Read in the sideset ids
    1096         [ +  - ]:         13 :     std::vector< int > id_array( numberSideSets_loading );
    1097                 :         13 :     int temp_var = -1;
    1098 [ +  - ][ +  - ]:         13 :     GET_1D_INT_VAR( "ss_prop1", temp_var, id_array );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1099 [ -  + ][ #  # ]:         13 :     if( -1 == temp_var ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting ss_prop1 variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1100                 :            : 
    1101                 :            :     // Create a side set for each one
    1102                 :            :     int number_sides_in_set;
    1103                 :            :     int number_dist_factors_in_set;
    1104                 :            : 
    1105                 :            :     // Maybe there is already a sidesets meshset here we can append to
    1106         [ +  - ]:         26 :     Range child_meshsets;
    1107 [ +  - ][ -  + ]:         13 :     if( mdbImpl->get_entities_by_type( 0, MBENTITYSET, child_meshsets ) != MB_SUCCESS ) return MB_FAILURE;
    1108                 :            : 
    1109 [ +  - ][ +  - ]:         13 :     child_meshsets = subtract( child_meshsets, initRange );
    1110                 :            : 
    1111 [ +  - ][ +  - ]:         13 :     Range::iterator iter, end_iter;
    1112                 :            : 
    1113                 :            :     int i;
    1114         [ +  - ]:         26 :     std::vector< char > temp_string_storage( max_str_length + 1 );
    1115         [ +  - ]:         13 :     char* temp_string = &temp_string_storage[0];
    1116                 :            :     int temp_dim;
    1117         [ +  + ]:         62 :     for( i = 0; i < numberSideSets_loading; i++ )
    1118                 :            :     {
    1119                 :            :         // Get sideset parameters
    1120 [ +  - ][ +  - ]:         49 :         GET_DIMB( temp_dim, temp_string, "num_side_ss%d", i + 1, number_sides_in_set );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1121 [ +  - ][ +  - ]:         49 :         GET_DIMB( temp_dim, temp_string, "num_df_ss%d", i + 1, number_dist_factors_in_set );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1122                 :            : 
    1123                 :            :         // Size new arrays and get element and side lists
    1124         [ +  - ]:         49 :         std::vector< int > side_list( number_sides_in_set );
    1125 [ +  - ][ +  - ]:         98 :         std::vector< int > element_list( number_sides_in_set );
    1126                 :         49 :         INS_ID( temp_string, "side_ss%d", i + 1 );
    1127                 :         49 :         temp_var = -1;
    1128 [ +  - ][ +  - ]:         49 :         GET_1D_INT_VAR( temp_string, temp_var, side_list );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1129 [ -  + ][ #  # ]:         49 :         if( -1 == temp_var ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting sideset side variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1130                 :            : 
    1131                 :         49 :         INS_ID( temp_string, "elem_ss%d", i + 1 );
    1132                 :         49 :         temp_var = -1;
    1133 [ +  - ][ +  - ]:         49 :         GET_1D_INT_VAR( temp_string, temp_var, element_list );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1134 [ -  + ][ #  # ]:         49 :         if( -1 == temp_var ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting sideset elem variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1135                 :            : 
    1136 [ +  - ][ +  - ]:         98 :         std::vector< double > temp_dist_factor_vector;
    1137 [ +  - ][ +  - ]:         98 :         std::vector< EntityHandle > entities_to_add, reverse_entities;
         [ +  - ][ +  - ]
    1138                 :            :         // Create the sideset entities
    1139 [ +  - ][ +  - ]:         98 :         if( create_ss_elements( &element_list[0], &side_list[0], number_sides_in_set, number_dist_factors_in_set,
                 [ -  + ]
    1140         [ +  - ]:         49 :                                 entities_to_add, reverse_entities, temp_dist_factor_vector, i + 1 ) != MB_SUCCESS )
    1141                 :          0 :             return MB_FAILURE;
    1142                 :            : 
    1143                 :            :         // If there are elements to add
    1144 [ -  + ][ #  # ]:         49 :         if( !entities_to_add.empty() || !reverse_entities.empty() )
                 [ +  - ]
    1145                 :            :         {
    1146         [ +  - ]:         49 :             iter     = child_meshsets.begin();
    1147         [ +  - ]:         49 :             end_iter = child_meshsets.end();
    1148                 :            : 
    1149                 :         49 :             EntityHandle ss_handle = 0;
    1150 [ +  - ][ +  - ]:        435 :             for( ; iter != end_iter; ++iter )
                 [ +  + ]
    1151                 :            :             {
    1152                 :            :                 int sideset_id;
    1153 [ +  - ][ +  - ]:        386 :                 if( mdbImpl->tag_get_data( mNeumannSetTag, &( *iter ), 1, &sideset_id ) != MB_SUCCESS ) continue;
                 [ -  + ]
    1154                 :            : 
    1155 [ +  - ][ -  + ]:        386 :                 if( id_array[i] == sideset_id )
    1156                 :            :                 {
    1157                 :            :                     // Found the meshset
    1158         [ #  # ]:          0 :                     ss_handle = *iter;
    1159                 :        386 :                     break;
    1160                 :            :                 }
    1161                 :            :             }
    1162                 :            : 
    1163                 :            :             // If we didn't find a sideset already
    1164         [ +  - ]:         49 :             if( ss_handle == 0 )
    1165                 :            :             {
    1166 [ +  - ][ -  + ]:         49 :                 if( mdbImpl->create_meshset( MESHSET_ORDERED | MESHSET_TRACK_OWNER, ss_handle ) != MB_SUCCESS )
    1167                 :          0 :                     return MB_FAILURE;
    1168                 :            : 
    1169         [ -  + ]:         49 :                 if( ss_handle == 0 ) return MB_FAILURE;
    1170                 :            : 
    1171         [ +  - ]:         49 :                 int sideset_id = id_array[i];
    1172 [ +  - ][ -  + ]:         49 :                 if( mdbImpl->tag_set_data( mNeumannSetTag, &ss_handle, 1, &sideset_id ) != MB_SUCCESS )
    1173                 :          0 :                     return MB_FAILURE;
    1174 [ +  - ][ -  + ]:         49 :                 if( mdbImpl->tag_set_data( mGlobalIdTag, &ss_handle, 1, &sideset_id ) != MB_SUCCESS ) return MB_FAILURE;
    1175                 :            : 
    1176         [ -  + ]:         49 :                 if( !reverse_entities.empty() )
    1177                 :            :                 {
    1178                 :            :                     // Also make a reverse set to put in this set
    1179                 :            :                     EntityHandle reverse_set;
    1180 [ #  # ][ #  # ]:          0 :                     if( mdbImpl->create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, reverse_set ) != MB_SUCCESS )
    1181                 :         49 :                         return MB_FAILURE;
    1182                 :            : 
    1183                 :            :                     // Add the reverse set to the sideset set and the entities to the reverse set
    1184         [ #  # ]:          0 :                     ErrorCode result = mdbImpl->add_entities( ss_handle, &reverse_set, 1 );
    1185         [ #  # ]:          0 :                     if( MB_SUCCESS != result ) return result;
    1186                 :            : 
    1187 [ #  # ][ #  # ]:          0 :                     result = mdbImpl->add_entities( reverse_set, &reverse_entities[0], reverse_entities.size() );
    1188         [ #  # ]:          0 :                     if( MB_SUCCESS != result ) return result;
    1189                 :            : 
    1190                 :            :                     // Set the reverse tag
    1191                 :            :                     Tag sense_tag;
    1192                 :          0 :                     int dum_sense = 0;
    1193                 :            :                     result        = mdbImpl->tag_get_handle( "NEUSET_SENSE", 1, MB_TYPE_INTEGER, sense_tag,
    1194         [ #  # ]:          0 :                                                       MB_TAG_SPARSE | MB_TAG_CREAT, &dum_sense );
    1195         [ #  # ]:          0 :                     if( result != MB_SUCCESS ) return result;
    1196                 :          0 :                     dum_sense = -1;
    1197         [ #  # ]:          0 :                     result    = mdbImpl->tag_set_data( sense_tag, &reverse_set, 1, &dum_sense );
    1198         [ #  # ]:          0 :                     if( result != MB_SUCCESS ) return result;
    1199                 :            :                 }
    1200                 :            :             }
    1201                 :            : 
    1202         [ -  + ]:         98 :             if( mdbImpl->add_entities( ss_handle, ( entities_to_add.empty() ) ? NULL : &entities_to_add[0],
    1203 [ -  + ][ +  - ]:         98 :                                        entities_to_add.size() ) != MB_SUCCESS )
                 [ +  - ]
    1204                 :          0 :                 return MB_FAILURE;
    1205                 :            : 
    1206                 :            :             // Distribution factor stuff
    1207         [ +  - ]:         49 :             if( number_dist_factors_in_set )
    1208                 :            :             {
    1209                 :            :                 // If this sideset does not already has a distribution factor array...set one
    1210                 :         49 :                 const void* ptr = 0;
    1211                 :         49 :                 int size        = 0;
    1212 [ +  - ][ -  + ]:         49 :                 if( MB_SUCCESS == mdbImpl->tag_get_by_ptr( mDistFactorTag, &ss_handle, 1, &ptr, &size ) )
    1213                 :            :                 {
    1214                 :          0 :                     const double* data = reinterpret_cast< const double* >( ptr );
    1215 [ #  # ][ #  # ]:          0 :                     std::copy( data, data + size, std::back_inserter( temp_dist_factor_vector ) );
    1216                 :            :                 }
    1217                 :            : 
    1218         [ +  - ]:         49 :                 ptr  = &temp_dist_factor_vector[0];
    1219                 :         49 :                 size = temp_dist_factor_vector.size();
    1220 [ +  - ][ -  + ]:         49 :                 if( mdbImpl->tag_set_by_ptr( mDistFactorTag, &ss_handle, 1, &ptr, &size ) != MB_SUCCESS )
    1221         [ +  - ]:         49 :                     return MB_FAILURE;
    1222                 :            :             }
    1223                 :            :         }
    1224                 :         49 :     }
    1225                 :            : 
    1226                 :         38 :     return MB_SUCCESS;
    1227                 :            : }
    1228                 :            : 
    1229                 :         49 : ErrorCode ReadNCDF::create_ss_elements( int* element_ids, int* side_list, int num_sides, int num_dist_factors,
    1230                 :            :                                         std::vector< EntityHandle >& entities_to_add,
    1231                 :            :                                         std::vector< EntityHandle >& reverse_entities,
    1232                 :            :                                         std::vector< double >& dist_factor_vector, int ss_seq_id )
    1233                 :            : {
    1234                 :            :     // Determine entity type from element id
    1235                 :            : 
    1236                 :            :     // If there are dist. factors, create a vector to hold the array
    1237                 :            :     // and place this array as a tag onto the sideset meshset
    1238                 :            : 
    1239         [ +  - ]:         49 :     std::vector< double > temp_dist_factor_vector( num_dist_factors );
    1240         [ +  - ]:         98 :     std::vector< char > temp_string_storage( max_str_length + 1 );
    1241         [ +  - ]:         49 :     char* temp_string = &temp_string_storage[0];
    1242                 :            :     int temp_var;
    1243         [ +  - ]:         49 :     if( num_dist_factors )
    1244                 :            :     {
    1245                 :         49 :         INS_ID( temp_string, "dist_fact_ss%d", ss_seq_id );
    1246                 :         49 :         temp_var = -1;
    1247 [ +  - ][ +  - ]:         49 :         GET_1D_DBL_VAR( temp_string, temp_var, temp_dist_factor_vector );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
    1248 [ -  + ][ #  # ]:         49 :         if( -1 == temp_var ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting dist fact variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1249                 :            :     }
    1250                 :            : 
    1251                 :            :     EntityType subtype;
    1252                 :            :     int num_side_nodes, num_elem_nodes;
    1253                 :            :     const EntityHandle* nodes;
    1254         [ +  - ]:         98 :     std::vector< EntityHandle > connectivity;
    1255                 :            :     int side_node_idx[32];
    1256                 :            : 
    1257                 :         49 :     int df_index = 0;
    1258                 :         49 :     int sense    = 0;
    1259         [ +  + ]:        422 :     for( int i = 0; i < num_sides; i++ )
    1260                 :            :     {
    1261                 :            :         ExoIIElementType exoii_type;
    1262         [ +  - ]:        373 :         ReadBlockData block_data;
    1263                 :        373 :         block_data.elemType = EXOII_MAX_ELEM_TYPE;
    1264                 :            : 
    1265 [ +  - ][ -  + ]:        373 :         if( find_side_element_type( element_ids[i], exoii_type, block_data, df_index, side_list[i] ) != MB_SUCCESS )
    1266                 :          0 :             continue;  // Isn't being read in this time
    1267                 :            : 
    1268                 :        373 :         EntityType type = ExoIIUtil::ExoIIElementMBEntity[exoii_type];
    1269                 :            : 
    1270                 :        373 :         EntityHandle ent_handle = element_ids[i] - block_data.startExoId + block_data.startMBId;
    1271                 :            : 
    1272                 :        373 :         const int side_num = side_list[i] - 1;
    1273         [ +  + ]:        373 :         if( type == MBHEX )
    1274                 :            :         {
    1275                 :            :             // Get the nodes of the element
    1276 [ +  - ][ -  + ]:        109 :             if( mdbImpl->get_connectivity( ent_handle, nodes, num_elem_nodes ) != MB_SUCCESS ) return MB_FAILURE;
    1277                 :            : 
    1278         [ +  - ]:        109 :             CN::SubEntityNodeIndices( type, num_elem_nodes, 2, side_num, subtype, num_side_nodes, side_node_idx );
    1279         [ -  + ]:        109 :             if( num_side_nodes <= 0 ) return MB_FAILURE;
    1280                 :            : 
    1281         [ +  - ]:        109 :             connectivity.resize( num_side_nodes );
    1282         [ +  + ]:        545 :             for( int k = 0; k < num_side_nodes; ++k )
    1283         [ +  - ]:        436 :                 connectivity[k] = nodes[side_node_idx[k]];
    1284                 :            : 
    1285 [ +  - ][ -  + ]:        109 :             if( MB_SUCCESS != create_sideset_element( connectivity, subtype, ent_handle, sense ) ) return MB_FAILURE;
    1286         [ +  - ]:        109 :             if( 1 == sense )
    1287         [ +  - ]:        109 :                 entities_to_add.push_back( ent_handle );
    1288                 :            :             else
    1289         [ #  # ]:          0 :                 reverse_entities.push_back( ent_handle );
    1290                 :            : 
    1291                 :            :             // Read in distribution factor array
    1292         [ +  - ]:        109 :             if( num_dist_factors )
    1293                 :            :             {
    1294         [ +  + ]:        545 :                 for( int k = 0; k < 4; k++ )
    1295 [ +  - ][ +  - ]:        436 :                     dist_factor_vector.push_back( temp_dist_factor_vector[df_index++] );
    1296                 :            :             }
    1297                 :            :         }
    1298                 :            : 
    1299                 :            :         // If it is a Tet
    1300         [ +  + ]:        264 :         else if( type == MBTET )
    1301                 :            :         {
    1302                 :            :             // Get the nodes of the element
    1303 [ +  - ][ -  + ]:        144 :             if( mdbImpl->get_connectivity( ent_handle, nodes, num_elem_nodes ) != MB_SUCCESS ) return MB_FAILURE;
    1304                 :            : 
    1305         [ +  - ]:        144 :             CN::SubEntityNodeIndices( type, num_elem_nodes, 2, side_num, subtype, num_side_nodes, side_node_idx );
    1306         [ -  + ]:        144 :             if( num_side_nodes <= 0 ) return MB_FAILURE;
    1307                 :            : 
    1308         [ +  - ]:        144 :             connectivity.resize( num_side_nodes );
    1309         [ +  + ]:        672 :             for( int k = 0; k < num_side_nodes; ++k )
    1310         [ +  - ]:        528 :                 connectivity[k] = nodes[side_node_idx[k]];
    1311                 :            : 
    1312 [ +  - ][ -  + ]:        144 :             if( MB_SUCCESS != create_sideset_element( connectivity, subtype, ent_handle, sense ) ) return MB_FAILURE;
    1313         [ +  - ]:        144 :             if( 1 == sense )
    1314         [ +  - ]:        144 :                 entities_to_add.push_back( ent_handle );
    1315                 :            :             else
    1316         [ #  # ]:          0 :                 reverse_entities.push_back( ent_handle );
    1317                 :            : 
    1318                 :            :             // Read in distribution factor array
    1319         [ +  - ]:        144 :             if( num_dist_factors )
    1320                 :            :             {
    1321         [ +  + ]:        576 :                 for( int k = 0; k < 3; k++ )
    1322 [ +  - ][ +  - ]:        432 :                     dist_factor_vector.push_back( temp_dist_factor_vector[df_index++] );
    1323                 :            :             }
    1324                 :            :         }
    1325 [ +  - ][ +  + ]:        120 :         else if( type == MBQUAD && exoii_type >= EXOII_SHELL && exoii_type <= EXOII_SHELL9 )
                 [ +  - ]
    1326                 :            :         {
    1327                 :            :             // ent_handle = CREATE_HANDLE(MBQUAD, base_id, error);
    1328                 :            : 
    1329                 :            :             // Just use this quad
    1330         [ -  + ]:         72 :             if( side_list[i] == 1 )
    1331                 :            :             {
    1332         [ #  # ]:          0 :                 if( 1 == sense )
    1333         [ #  # ]:          0 :                     entities_to_add.push_back( ent_handle );
    1334                 :            :                 else
    1335         [ #  # ]:          0 :                     reverse_entities.push_back( ent_handle );
    1336                 :            : 
    1337         [ #  # ]:          0 :                 if( num_dist_factors )
    1338                 :            :                 {
    1339         [ #  # ]:          0 :                     for( int k = 0; k < 4; k++ )
    1340 [ #  # ][ #  # ]:          0 :                         dist_factor_vector.push_back( temp_dist_factor_vector[df_index++] );
    1341                 :            :                 }
    1342                 :            : 
    1343                 :          0 :                 continue;
    1344                 :            :             }
    1345         [ -  + ]:         72 :             else if( side_list[i] == 2 )
    1346                 :            :             {
    1347         [ #  # ]:          0 :                 reverse_entities.push_back( ent_handle );
    1348                 :            : 
    1349         [ #  # ]:          0 :                 if( num_dist_factors )
    1350                 :            :                 {
    1351         [ #  # ]:          0 :                     for( int k = 0; k < 4; k++ )
    1352 [ #  # ][ #  # ]:          0 :                         dist_factor_vector.push_back( temp_dist_factor_vector[df_index++] );
    1353                 :            :                 }
    1354                 :            : 
    1355                 :          0 :                 continue;
    1356                 :            :             }
    1357                 :            :             else
    1358                 :            :             {
    1359                 :            :                 // Get the nodes of the element
    1360 [ +  - ][ -  + ]:         72 :                 if( mdbImpl->get_connectivity( ent_handle, nodes, num_elem_nodes ) != MB_SUCCESS ) return MB_FAILURE;
    1361                 :            : 
    1362                 :            :                 CN::SubEntityNodeIndices( type, num_elem_nodes, 1, side_num - 2, subtype, num_side_nodes,
    1363         [ +  - ]:         72 :                                           side_node_idx );
    1364         [ -  + ]:         72 :                 if( num_side_nodes <= 0 ) return MB_FAILURE;
    1365                 :            : 
    1366         [ +  - ]:         72 :                 connectivity.resize( num_side_nodes );
    1367         [ +  + ]:        216 :                 for( int k = 0; k < num_side_nodes; ++k )
    1368         [ +  - ]:        144 :                     connectivity[k] = nodes[side_node_idx[k]];
    1369                 :            : 
    1370 [ +  - ][ -  + ]:         72 :                 if( MB_SUCCESS != create_sideset_element( connectivity, subtype, ent_handle, sense ) )
    1371                 :          0 :                     return MB_FAILURE;
    1372         [ +  - ]:         72 :                 if( 1 == sense )
    1373         [ +  - ]:         72 :                     entities_to_add.push_back( ent_handle );
    1374                 :            :                 else
    1375         [ #  # ]:          0 :                     reverse_entities.push_back( ent_handle );
    1376                 :            : 
    1377         [ +  - ]:         72 :                 if( num_dist_factors )
    1378                 :            :                 {
    1379         [ +  + ]:        216 :                     for( int k = 0; k < 2; k++ )
    1380 [ +  - ][ +  - ]:        144 :                         dist_factor_vector.push_back( temp_dist_factor_vector[df_index++] );
    1381                 :            :                 }
    1382                 :         72 :             }
    1383                 :            :         }
    1384                 :            :         // If it is a Quad
    1385         [ +  - ]:         48 :         else if( type == MBQUAD )
    1386                 :            :         {
    1387                 :            :             // Get the nodes of the element
    1388 [ +  - ][ -  + ]:         48 :             if( mdbImpl->get_connectivity( ent_handle, nodes, num_elem_nodes ) != MB_SUCCESS ) return MB_FAILURE;
    1389                 :            : 
    1390         [ +  - ]:         48 :             CN::SubEntityNodeIndices( type, num_elem_nodes, 1, side_num, subtype, num_side_nodes, side_node_idx );
    1391         [ -  + ]:         48 :             if( num_side_nodes <= 0 ) return MB_FAILURE;
    1392                 :            : 
    1393         [ +  - ]:         48 :             connectivity.resize( num_side_nodes );
    1394         [ +  + ]:        144 :             for( int k = 0; k < num_side_nodes; ++k )
    1395         [ +  - ]:         96 :                 connectivity[k] = nodes[side_node_idx[k]];
    1396                 :            : 
    1397 [ +  - ][ -  + ]:         48 :             if( MB_SUCCESS != create_sideset_element( connectivity, subtype, ent_handle, sense ) ) return MB_FAILURE;
    1398         [ +  - ]:         48 :             if( 1 == sense )
    1399         [ +  - ]:         48 :                 entities_to_add.push_back( ent_handle );
    1400                 :            :             else
    1401         [ #  # ]:          0 :                 reverse_entities.push_back( ent_handle );
    1402                 :            : 
    1403                 :            :             // Read in distribution factor array
    1404         [ +  - ]:         48 :             if( num_dist_factors )
    1405                 :            :             {
    1406         [ +  + ]:        144 :                 for( int k = 0; k < 2; k++ )
    1407 [ +  - ][ +  - ]:         96 :                     dist_factor_vector.push_back( temp_dist_factor_vector[df_index++] );
    1408                 :            :             }
    1409                 :            :         }
    1410         [ #  # ]:          0 :         else if( type == MBTRI )
    1411                 :            :         {
    1412                 :          0 :             int side_offset = 0;
    1413 [ #  # ][ #  # ]:          0 :             if( number_dimensions() == 3 && side_list[i] <= 2 )
         [ #  # ][ #  # ]
    1414                 :            :             {
    1415         [ #  # ]:          0 :                 if( 1 == sense )
    1416         [ #  # ]:          0 :                     entities_to_add.push_back( ent_handle );
    1417                 :            :                 else
    1418         [ #  # ]:          0 :                     reverse_entities.push_back( ent_handle );
    1419         [ #  # ]:          0 :                 if( num_dist_factors )
    1420                 :            :                 {
    1421         [ #  # ]:          0 :                     for( int k = 0; k < 3; k++ )
    1422 [ #  # ][ #  # ]:          0 :                         dist_factor_vector.push_back( temp_dist_factor_vector[df_index++] );
    1423                 :            :                 }
    1424                 :            :             }
    1425                 :            :             else
    1426                 :            :             {
    1427 [ #  # ][ #  # ]:          0 :                 if( number_dimensions() == 3 )
    1428                 :            :                 {
    1429         [ #  # ]:          0 :                     if( side_list[i] > 2 ) side_offset = 2;
    1430                 :            :                 }
    1431                 :            : 
    1432                 :            :                 // Get the nodes of the element
    1433 [ #  # ][ #  # ]:          0 :                 if( mdbImpl->get_connectivity( ent_handle, nodes, num_elem_nodes ) != MB_SUCCESS ) return MB_FAILURE;
    1434                 :            : 
    1435                 :            :                 CN::SubEntityNodeIndices( type, num_elem_nodes, 1, side_num - side_offset, subtype, num_side_nodes,
    1436         [ #  # ]:          0 :                                           side_node_idx );
    1437         [ #  # ]:          0 :                 if( num_side_nodes <= 0 ) return MB_FAILURE;
    1438                 :            : 
    1439         [ #  # ]:          0 :                 connectivity.resize( num_side_nodes );
    1440         [ #  # ]:          0 :                 for( int k = 0; k < num_side_nodes; ++k )
    1441         [ #  # ]:          0 :                     connectivity[k] = nodes[side_node_idx[k]];
    1442                 :            : 
    1443 [ #  # ][ #  # ]:          0 :                 if( MB_SUCCESS != create_sideset_element( connectivity, subtype, ent_handle, sense ) )
    1444                 :          0 :                     return MB_FAILURE;
    1445         [ #  # ]:          0 :                 if( 1 == sense )
    1446         [ #  # ]:          0 :                     entities_to_add.push_back( ent_handle );
    1447                 :            :                 else
    1448         [ #  # ]:          0 :                     reverse_entities.push_back( ent_handle );
    1449                 :            : 
    1450         [ #  # ]:          0 :                 if( num_dist_factors )
    1451                 :            :                 {
    1452         [ #  # ]:        373 :                     for( int k = 0; k < 2; k++ )
              [ +  -  - ]
    1453 [ #  # ][ #  # ]:          0 :                         dist_factor_vector.push_back( temp_dist_factor_vector[df_index++] );
    1454                 :            :                 }
    1455                 :            :             }
    1456                 :            :         }
    1457                 :        373 :     }
    1458                 :            : 
    1459                 :         98 :     return MB_SUCCESS;
    1460                 :            : }
    1461                 :            : 
    1462                 :        373 : ErrorCode ReadNCDF::create_sideset_element( const std::vector< EntityHandle >& connectivity, EntityType type,
    1463                 :            :                                             EntityHandle& handle, int& sense )
    1464                 :            : {
    1465                 :            :     // Get adjacent entities
    1466                 :        373 :     ErrorCode error = MB_SUCCESS;
    1467         [ +  - ]:        373 :     int to_dim      = CN::Dimension( type );
    1468                 :            :     // for matching purposes , consider only corner nodes
    1469                 :            :     // basically, assume everything is matching if the corner nodes are matching, and
    1470                 :            :     // the number of total nodes is the same
    1471         [ +  - ]:        373 :     int nb_corner_nodes = CN::VerticesPerEntity( type );
    1472         [ +  - ]:        373 :     std::vector< EntityHandle > adj_ent;
    1473 [ +  - ][ +  - ]:        373 :     mdbImpl->get_adjacencies( &( connectivity[0] ), 1, to_dim, false, adj_ent );
    1474                 :            : 
    1475                 :            :     // For each entity, see if we can find a match
    1476                 :            :     // If we find a match, return it
    1477                 :        373 :     bool match_found = false;
    1478         [ +  - ]:        746 :     std::vector< EntityHandle > match_conn;
    1479                 :            :     // By default, assume positive sense
    1480                 :        373 :     sense = 1;
    1481 [ +  + ][ +  + ]:        999 :     for( unsigned int i = 0; i < adj_ent.size() && match_found == false; i++ )
                 [ +  + ]
    1482                 :            :     {
    1483                 :            :         // Get the connectivity
    1484 [ +  - ][ +  - ]:        626 :         error = mdbImpl->get_connectivity( &( adj_ent[i] ), 1, match_conn );
    1485         [ -  + ]:        668 :         if( error != MB_SUCCESS ) continue;
    1486                 :            : 
    1487                 :            :         // Make sure they have the same number of vertices (higher order elements ?)
    1488         [ +  + ]:        626 :         if( match_conn.size() != connectivity.size() ) continue;
    1489                 :            : 
    1490                 :            :         // Find a matching node
    1491                 :        584 :         std::vector< EntityHandle >::iterator iter;
    1492         [ +  - ]:        584 :         std::vector< EntityHandle >::iterator end_corner = match_conn.begin() + nb_corner_nodes;
    1493 [ +  - ][ +  - ]:        584 :         iter                                             = std::find( match_conn.begin(), end_corner, connectivity[0] );
    1494 [ +  - ][ -  + ]:        584 :         if( iter == end_corner ) continue;
    1495                 :            : 
    1496                 :            :         // Rotate to match connectivity
    1497                 :            :         // rotate only corner nodes, ignore the rest from now on
    1498         [ +  - ]:        584 :         std::rotate( match_conn.begin(), iter, end_corner );
    1499                 :            : 
    1500                 :        584 :         bool they_match = true;
    1501         [ +  + ]:        704 :         for( int j = 1; j < nb_corner_nodes; j++ )
    1502                 :            :         {
    1503 [ +  - ][ +  - ]:        656 :             if( connectivity[j] != match_conn[j] )
                 [ +  + ]
    1504                 :            :             {
    1505                 :        536 :                 they_match = false;
    1506                 :        536 :                 break;
    1507                 :            :             }
    1508                 :            :         }
    1509                 :            : 
    1510                 :            :         // If we didn't get a match
    1511         [ +  + ]:        584 :         if( !they_match )
    1512                 :            :         {
    1513                 :            :             // Try the opposite sense
    1514                 :        536 :             they_match = true;
    1515                 :            : 
    1516                 :        536 :             int k = nb_corner_nodes - 1;
    1517         [ +  - ]:        664 :             for( int j = 1; j < nb_corner_nodes; )
    1518                 :            :             {
    1519 [ +  - ][ +  - ]:        664 :                 if( connectivity[j] != match_conn[k] )
                 [ +  + ]
    1520                 :            :                 {
    1521                 :        536 :                     they_match = false;
    1522                 :        536 :                     break;
    1523                 :            :                 }
    1524                 :        128 :                 ++j;
    1525                 :        128 :                 --k;
    1526                 :            :             }
    1527                 :            :             // If they matched here, sense is reversed
    1528         [ -  + ]:        536 :             if( they_match ) sense = -1;
    1529                 :            :         }
    1530                 :        584 :         match_found = they_match;
    1531 [ +  + ][ +  - ]:        584 :         if( match_found ) handle = adj_ent[i];
    1532                 :            :     }
    1533                 :            : 
    1534                 :            :     // If we didn't find a match, create an element
    1535 [ +  + ][ +  - ]:        373 :     if( !match_found ) error = mdbImpl->create_element( type, &connectivity[0], connectivity.size(), handle );
                 [ +  - ]
    1536                 :            : 
    1537                 :        373 :     return error;
    1538                 :            : }
    1539                 :            : 
    1540                 :        373 : ErrorCode ReadNCDF::find_side_element_type( const int exodus_id, ExoIIElementType& elem_type, ReadBlockData& block_data,
    1541                 :            :                                             int& df_index, int side_id )
    1542                 :            : {
    1543                 :        373 :     std::vector< ReadBlockData >::iterator iter, end_iter;
    1544                 :        373 :     iter      = blocksLoading.begin();
    1545                 :        373 :     end_iter  = blocksLoading.end();
    1546                 :        373 :     elem_type = EXOII_MAX_ELEM_TYPE;
    1547                 :            : 
    1548 [ +  - ][ +  - ]:        781 :     for( ; iter != end_iter; ++iter )
                 [ +  - ]
    1549                 :            :     {
    1550 [ +  - ][ +  - ]:        781 :         if( exodus_id >= ( *iter ).startExoId && exodus_id < ( *iter ).startExoId + ( *iter ).numElements )
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
    1551                 :            :         {
    1552         [ +  - ]:        373 :             elem_type = ( *iter ).elemType;
    1553                 :            : 
    1554                 :            :             // If we're not reading this block in
    1555 [ +  - ][ -  + ]:        373 :             if( !( *iter ).reading_in )
    1556                 :            :             {
    1557                 :            :                 // Offset df_indes according to type
    1558 [ #  # ][ #  # ]:          0 :                 if( elem_type >= EXOII_HEX && elem_type <= EXOII_HEX27 )
    1559                 :          0 :                     df_index += 4;
    1560 [ #  # ][ #  # ]:          0 :                 else if( elem_type >= EXOII_TETRA && elem_type <= EXOII_TETRA14 )
    1561                 :          0 :                     df_index += 3;
    1562 [ #  # ][ #  # ]:          0 :                 else if( elem_type >= EXOII_QUAD && elem_type <= EXOII_QUAD9 )
    1563                 :          0 :                     df_index += 2;
    1564 [ #  # ][ #  # ]:          0 :                 else if( elem_type >= EXOII_SHELL && elem_type <= EXOII_SHELL9 )
    1565                 :            :                 {
    1566 [ #  # ][ #  # ]:          0 :                     if( side_id == 1 || side_id == 2 )
    1567                 :          0 :                         df_index += 4;
    1568                 :            :                     else
    1569                 :          0 :                         df_index += 2;
    1570                 :            :                 }
    1571 [ #  # ][ #  # ]:          0 :                 else if( elem_type >= EXOII_TRI && elem_type <= EXOII_TRI7 )
    1572                 :          0 :                     df_index += 3;
    1573                 :            : 
    1574                 :          0 :                 return MB_FAILURE;
    1575                 :            :             }
    1576                 :            : 
    1577 [ +  - ][ +  - ]:        373 :             block_data = *iter;
    1578                 :            : 
    1579                 :        373 :             return MB_SUCCESS;
    1580                 :            :         }
    1581                 :            :     }
    1582                 :        373 :     return MB_FAILURE;
    1583                 :            : }
    1584                 :            : 
    1585                 :          2 : ErrorCode ReadNCDF::read_qa_records( EntityHandle file_set )
    1586                 :            : {
    1587         [ +  - ]:          2 :     std::vector< std::string > qa_records;
    1588         [ +  - ]:          2 :     read_qa_information( qa_records );
    1589                 :            : 
    1590         [ +  - ]:          4 :     std::vector< char > tag_data;
    1591 [ +  - ][ +  - ]:         10 :     for( std::vector< std::string >::iterator i = qa_records.begin(); i != qa_records.end(); ++i )
                 [ +  + ]
    1592                 :            :     {
    1593 [ +  - ][ +  - ]:          8 :         std::copy( i->begin(), i->end(), std::back_inserter( tag_data ) );
         [ +  - ][ +  - ]
    1594         [ +  - ]:          8 :         tag_data.push_back( '\0' );
    1595                 :            :     }
    1596                 :            : 
    1597                 :            :     // If there were qa_records...tag them to the mCurrentMeshHandle
    1598         [ +  - ]:          2 :     if( !tag_data.empty() )
    1599                 :            :     {
    1600         [ +  - ]:          2 :         const void* ptr = &tag_data[0];
    1601                 :          2 :         int size        = tag_data.size();
    1602 [ +  - ][ -  + ]:          2 :         if( mdbImpl->tag_set_by_ptr( mQaRecordTag, &file_set, 1, &ptr, &size ) != MB_SUCCESS ) { return MB_FAILURE; }
    1603                 :            :     }
    1604                 :            : 
    1605                 :          4 :     return MB_SUCCESS;
    1606                 :            : }
    1607                 :            : 
    1608                 :          2 : ErrorCode ReadNCDF::read_qa_information( std::vector< std::string >& qa_record_list )
    1609                 :            : {
    1610                 :            :     // Inquire on the genesis file to find the number of qa records
    1611                 :            : 
    1612                 :          2 :     int number_records = 0;
    1613                 :            : 
    1614                 :            :     int temp_dim;
    1615 [ +  - ][ +  - ]:          2 :     GET_DIM( temp_dim, "num_qa_rec", number_records );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1616         [ +  - ]:          2 :     std::vector< char > data( max_str_length + 1 );
    1617                 :            : 
    1618         [ +  + ]:          4 :     for( int i = 0; i < number_records; i++ )
    1619                 :            :     {
    1620         [ +  + ]:         10 :         for( int j = 0; j < 4; j++ )
    1621                 :            :         {
    1622         [ +  - ]:          8 :             data[max_str_length] = '\0';
    1623 [ +  - ][ +  - ]:          8 :             if( read_qa_string( &data[0], i, j ) != MB_SUCCESS ) return MB_FAILURE;
                 [ -  + ]
    1624                 :            : 
    1625 [ +  - ][ +  - ]:          8 :             qa_record_list.push_back( &data[0] );
                 [ +  - ]
    1626                 :            :         }
    1627                 :            :     }
    1628                 :            : 
    1629                 :          2 :     return MB_SUCCESS;
    1630                 :            : }
    1631                 :            : 
    1632                 :          8 : ErrorCode ReadNCDF::read_qa_string( char* temp_string, int record_number, int record_position )
    1633                 :            : {
    1634         [ +  - ]:          8 :     std::vector< int > dims;
    1635                 :          8 :     int temp_var = -1;
    1636 [ +  - ][ +  - ]:          8 :     GET_VAR( "qa_records", temp_var, dims );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1637         [ -  + ]:          8 :     if( -1 == temp_var )
    1638                 :            :     {
    1639 [ #  # ][ #  # ]:          0 :         MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting qa record variable" );
         [ #  # ][ #  # ]
                 [ #  # ]
    1640                 :            :         return MB_FAILURE;
    1641                 :            :     }
    1642                 :            :     size_t count[3], start[3];
    1643                 :          8 :     start[0] = record_number;
    1644                 :          8 :     start[1] = record_position;
    1645                 :          8 :     start[2] = 0;
    1646                 :          8 :     count[0] = 1;
    1647                 :          8 :     count[1] = 1;
    1648                 :          8 :     count[2] = max_str_length;
    1649         [ +  - ]:          8 :     int fail = nc_get_vara_text( ncFile, temp_var, start, count, temp_string );
    1650         [ -  + ]:          8 :     if( NC_NOERR != fail )
    1651 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem setting current record number variable position" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
    1652                 :            :     // Get the variable id in the exodus file
    1653                 :            : 
    1654                 :          8 :     return MB_SUCCESS;
    1655                 :            : }
    1656                 :            : 
    1657                 :            : // The cub_file_set contains the mesh to be updated. There could exist other
    1658                 :            : // file sets that should be kept separate, such as the geometry file set from
    1659                 :            : // ReadCGM.
    1660                 :          0 : ErrorCode ReadNCDF::update( const char* exodus_file_name, const FileOptions& opts, const int num_blocks,
    1661                 :            :                             const int* blocks_to_load, const EntityHandle cub_file_set )
    1662                 :            : {
    1663                 :            :     // Function : updating current database from new exodus_file.
    1664                 :            :     // Creator:   Jane Hu
    1665                 :            :     // opts is currently designed as following
    1666                 :            :     // tdata = <var_name>[, time][,op][,destination]
    1667                 :            :     // where var_name show the tag name to be updated, this version just takes
    1668                 :            :     // coord.
    1669                 :            :     // time is the optional, and it gives time step of each of the mesh
    1670                 :            :     // info in exodus file. It start from 1.
    1671                 :            :     // op is the operation that is going to be performed on the var_name info.
    1672                 :            :     // currently support 'set'
    1673                 :            :     // destination shows where to store the updated info, currently assume it is
    1674                 :            :     // stored in the same database by replacing the old info if there's no input
    1675                 :            :     // for destination, or the destination data is given in exodus format and just
    1676                 :            :     // need to update the coordinates.
    1677                 :            :     // Assumptions:
    1678                 :            :     // 1. Assume the num_el_blk's in both DB and update exodus file are the same.
    1679                 :            :     // 2. Assume num_el_in_blk1...num_el_in_blk(num_el_blk) numbers are matching, may in
    1680                 :            :     // different order. example: num_el_in_blk11 = num_el_in_blk22 && num_el_in_blk12 =
    1681                 :            :     // num_el_in_blk21.
    1682                 :            :     // 3. In exodus file, get node_num_map
    1683                 :            :     // 4. loop through the node_num_map, use it to find the node in the cub file.
    1684                 :            :     // 5. Replace coord[0][n] with coordx[m] + vals_nod_var1(time_step, m) for all directions for
    1685                 :            :     // matching nodes.
    1686                 :            :     //  Test: try to get hexes
    1687                 :            : 
    1688                 :            :     // *******************************************************************
    1689                 :            :     // Move nodes to their deformed locations.
    1690                 :            :     // *******************************************************************
    1691                 :            :     ErrorCode rval;
    1692         [ #  # ]:          0 :     std::string s;
    1693         [ #  # ]:          0 :     rval = opts.get_str_option( "tdata", s );
    1694 [ #  # ][ #  # ]:          0 :     if( MB_SUCCESS != rval ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem reading file options" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1695         [ #  # ]:          0 :     std::vector< std::string > tokens;
    1696         [ #  # ]:          0 :     tokenize( s, tokens, "," );
    1697                 :            : 
    1698                 :            :     // 1. Check for time step to find the match time
    1699                 :          0 :     int time_step = 1;
    1700 [ #  # ][ #  # ]:          0 :     if( tokens.size() > 1 && !tokens[1].empty() )
         [ #  # ][ #  # ]
    1701                 :            :     {
    1702         [ #  # ]:          0 :         const char* time_s = tokens[1].c_str();
    1703                 :            :         char* endptr;
    1704                 :          0 :         long int pval   = strtol( time_s, &endptr, 0 );
    1705         [ #  # ]:          0 :         std::string end = endptr;
    1706         [ #  # ]:          0 :         if( !end.empty() )  // Syntax error
    1707                 :          0 :             return MB_TYPE_OUT_OF_RANGE;
    1708                 :            : 
    1709                 :            :         // Check for overflow (parsing long int, returning int)
    1710                 :          0 :         time_step = pval;
    1711         [ #  # ]:          0 :         if( pval != (long int)time_step ) return MB_TYPE_OUT_OF_RANGE;
    1712 [ #  # ][ #  # ]:          0 :         if( time_step <= 0 ) return MB_TYPE_OUT_OF_RANGE;
    1713                 :            :     }
    1714                 :            : 
    1715                 :            :     // 2. Check for the operations, currently support set.
    1716                 :            :     const char* op;
    1717 [ #  # ][ #  # ]:          0 :     if( tokens.size() < 3 || ( tokens[2] != "set" && tokens[2] != "add" ) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1718 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_TYPE_OUT_OF_RANGE, "ReadNCDF: invalid operation specified for update" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
    1719         [ #  # ]:          0 :     op = tokens[2].c_str();
    1720                 :            : 
    1721                 :            :     // Open netcdf/exodus file
    1722                 :          0 :     ncFile   = 0;
    1723         [ #  # ]:          0 :     int fail = nc_open( exodus_file_name, 0, &ncFile );
    1724         [ #  # ]:          0 :     if( !ncFile )
    1725 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, "ReadNCDF:: problem opening Netcdf/Exodus II file " << exodus_file_name ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1726                 :            : 
    1727         [ #  # ]:          0 :     rval = read_exodus_header();
    1728         [ #  # ]:          0 :     if( MB_SUCCESS != rval ) return rval;
    1729                 :            : 
    1730                 :            :     // Check to make sure that the requested time step exists
    1731                 :          0 :     int ncdim = -1;
    1732                 :            :     int max_time_steps;
    1733 [ #  # ][ #  # ]:          0 :     GET_DIM( ncdim, "time_step", max_time_steps );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1734         [ #  # ]:          0 :     if( -1 == ncdim )
    1735                 :            :     {
    1736 [ #  # ][ #  # ]:          0 :         std::cout << "ReadNCDF: could not get number of time steps" << std::endl;
    1737                 :          0 :         return MB_FAILURE;
    1738                 :            :     }
    1739 [ #  # ][ #  # ]:          0 :     std::cout << "  Maximum time step=" << max_time_steps << std::endl;
                 [ #  # ]
    1740         [ #  # ]:          0 :     if( max_time_steps < time_step )
    1741                 :            :     {
    1742 [ #  # ][ #  # ]:          0 :         std::cout << "ReadNCDF: time step is greater than max_time_steps" << std::endl;
    1743                 :          0 :         return MB_FAILURE;
    1744                 :            :     }
    1745                 :            : 
    1746                 :            :     // Get the time
    1747         [ #  # ]:          0 :     std::vector< double > times( max_time_steps );
    1748                 :          0 :     int nc_var = -1;
    1749 [ #  # ][ #  # ]:          0 :     GET_1D_DBL_VAR( "time_whole", nc_var, times );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1750 [ #  # ][ #  # ]:          0 :     if( -1 == nc_var ) { std::cout << "ReadNCDF: unable to get time variable" << std::endl; }
                 [ #  # ]
    1751                 :            :     else
    1752                 :            :     {
    1753 [ #  # ][ #  # ]:          0 :         std::cout << "  Step " << time_step << " is at " << times[time_step - 1] << " seconds" << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1754                 :            :     }
    1755                 :            : 
    1756                 :            :     // Read in the node_num_map.
    1757         [ #  # ]:          0 :     std::vector< int > ptr( numberNodes_loading );
    1758                 :            : 
    1759                 :          0 :     int varid = -1;
    1760 [ #  # ][ #  # ]:          0 :     GET_1D_INT_VAR( "node_num_map", varid, ptr );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1761 [ #  # ][ #  # ]:          0 :     if( -1 == varid ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting node number map data" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1762                 :            : 
    1763                 :            :     // Read in the deformations.
    1764         [ #  # ]:          0 :     std::vector< std::vector< double > > deformed_arrays( 3 );
    1765         [ #  # ]:          0 :     std::vector< std::vector< double > > orig_coords( 3 );
    1766 [ #  # ][ #  # ]:          0 :     deformed_arrays[0].reserve( numberNodes_loading );
    1767 [ #  # ][ #  # ]:          0 :     deformed_arrays[1].reserve( numberNodes_loading );
    1768 [ #  # ][ #  # ]:          0 :     deformed_arrays[2].reserve( numberNodes_loading );
    1769 [ #  # ][ #  # ]:          0 :     orig_coords[0].reserve( numberNodes_loading );
    1770 [ #  # ][ #  # ]:          0 :     orig_coords[1].reserve( numberNodes_loading );
    1771 [ #  # ][ #  # ]:          0 :     orig_coords[2].reserve( numberNodes_loading );
    1772                 :          0 :     size_t start[2] = { static_cast< size_t >( time_step - 1 ), 0 },
    1773                 :          0 :            count[2] = { 1, static_cast< size_t >( numberNodes_loading ) };
    1774         [ #  # ]:          0 :     std::vector< int > dims;
    1775                 :          0 :     int coordx = -1, coordy = -1, coordz = -1;
    1776 [ #  # ][ #  # ]:          0 :     GET_VAR( "vals_nod_var1", coordx, dims );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1777 [ #  # ][ #  # ]:          0 :     GET_VAR( "vals_nod_var2", coordy, dims );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1778 [ #  # ][ #  # ]:          0 :     if( numberDimensions_loading == 3 ) GET_VAR( "vals_nod_var3", coordz, dims );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1779 [ #  # ][ #  # ]:          0 :     if( -1 == coordx || -1 == coordy || ( numberDimensions_loading == 3 && -1 == coordz ) )
         [ #  # ][ #  # ]
    1780 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting coords variable" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
    1781                 :            : 
    1782 [ #  # ][ #  # ]:          0 :     fail = nc_get_vara_double( ncFile, coordx, start, count, &deformed_arrays[0][0] );
                 [ #  # ]
    1783 [ #  # ][ #  # ]:          0 :     if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting x deformation array" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1784                 :            : 
    1785 [ #  # ][ #  # ]:          0 :     fail = nc_get_vara_double( ncFile, coordy, start, count, &deformed_arrays[1][0] );
                 [ #  # ]
    1786 [ #  # ][ #  # ]:          0 :     if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting y deformation array" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1787         [ #  # ]:          0 :     if( numberDimensions_loading == 3 )
    1788                 :            :     {
    1789 [ #  # ][ #  # ]:          0 :         fail = nc_get_vara_double( ncFile, coordz, start, count, &deformed_arrays[2][0] );
                 [ #  # ]
    1790 [ #  # ][ #  # ]:          0 :         if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting z deformation array" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1791                 :            :     }
    1792                 :            : 
    1793                 :          0 :     int coord1 = -1, coord2 = -1, coord3 = -1;
    1794 [ #  # ][ #  # ]:          0 :     GET_1D_DBL_VAR( "coordx", coord1, orig_coords[0] );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1795 [ #  # ][ #  # ]:          0 :     if( -1 == coord1 ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting x coord array" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1796 [ #  # ][ #  # ]:          0 :     GET_1D_DBL_VAR( "coordy", coord2, orig_coords[1] );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1797 [ #  # ][ #  # ]:          0 :     if( -1 == coord2 ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting y coord array" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1798         [ #  # ]:          0 :     if( numberDimensions_loading == 3 )
    1799                 :            :     {
    1800 [ #  # ][ #  # ]:          0 :         GET_1D_DBL_VAR( "coordz", coord3, orig_coords[2] );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1801 [ #  # ][ #  # ]:          0 :         if( -1 == coord3 ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting z coord array" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1802                 :            :     }
    1803                 :            : 
    1804                 :            :     // b. Deal with DB file : get node info. according to node_num_map.
    1805 [ #  # ][ #  # ]:          0 :     if( tokens[0] != "coord" && tokens[0] != "COORD" ) return MB_NOT_IMPLEMENTED;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1806                 :            : 
    1807 [ #  # ][ #  # ]:          0 :     if( strcmp( op, "set" ) && strcmp( op, " set" ) ) return MB_NOT_IMPLEMENTED;
    1808                 :            : 
    1809                 :            :     // Two methods of matching nodes (id vs. proximity)
    1810                 :          0 :     const bool match_node_ids = true;
    1811                 :            : 
    1812                 :            :     // Get nodes in cubit file
    1813         [ #  # ]:          0 :     Range cub_verts;
    1814         [ #  # ]:          0 :     rval = mdbImpl->get_entities_by_type( cub_file_set, MBVERTEX, cub_verts );
    1815         [ #  # ]:          0 :     if( MB_SUCCESS != rval ) return rval;
    1816 [ #  # ][ #  # ]:          0 :     std::cout << "  cub_file_set contains " << cub_verts.size() << " nodes." << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
    1817                 :            : 
    1818                 :            :     // Some accounting
    1819 [ #  # ][ #  # ]:          0 :     std::cout << "  exodus file contains " << numberNodes_loading << " nodes." << std::endl;
         [ #  # ][ #  # ]
    1820                 :          0 :     double max_magnitude     = 0;
    1821                 :          0 :     double average_magnitude = 0;
    1822                 :          0 :     int found                = 0;
    1823                 :          0 :     int lost                 = 0;
    1824         [ #  # ]:          0 :     std::map< int, EntityHandle > cub_verts_id_map;
    1825         [ #  # ]:          0 :     AdaptiveKDTree kdtree( mdbImpl );
    1826                 :            :     EntityHandle root;
    1827                 :            : 
    1828                 :            :     // Should not use cub verts unless they have been matched. Place in a map
    1829                 :            :     // for fast handle_by_id lookup.
    1830         [ #  # ]:          0 :     std::map< int, EntityHandle > matched_cub_vert_id_map;
    1831                 :            : 
    1832                 :            :     // Place cub verts in a map for searching by id
    1833                 :            :     if( match_node_ids )
    1834                 :            :     {
    1835 [ #  # ][ #  # ]:          0 :         std::vector< int > cub_ids( cub_verts.size() );
    1836 [ #  # ][ #  # ]:          0 :         rval = mdbImpl->tag_get_data( mGlobalIdTag, cub_verts, &cub_ids[0] );
    1837         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return rval;
    1838 [ #  # ][ #  # ]:          0 :         for( unsigned i = 0; i != cub_verts.size(); ++i )
                 [ #  # ]
    1839                 :            :         {
    1840 [ #  # ][ #  # ]:          0 :             cub_verts_id_map.insert( std::pair< int, EntityHandle >( cub_ids[i], cub_verts[i] ) );
         [ #  # ][ #  # ]
    1841                 :          0 :         }
    1842                 :            : 
    1843                 :            :         // Place cub verts in a kdtree for searching by proximity
    1844                 :            :     }
    1845                 :            :     else
    1846                 :            :     {
    1847                 :            :         FileOptions tree_opts( "MAX_PER_LEAF=1;SPLITS_PER_DIR=1;CANDIDATE_PLANE_SET=0" );
    1848                 :            :         rval = kdtree.build_tree( cub_verts, &root, &tree_opts );
    1849                 :            :         if( MB_SUCCESS != rval ) return rval;
    1850                 :            :         AdaptiveKDTreeIter tree_iter;
    1851                 :            :         rval = kdtree.get_tree_iterator( root, tree_iter );
    1852                 :            :         if( MB_SUCCESS != rval ) return rval;
    1853                 :            :     }
    1854                 :            : 
    1855                 :            :     // For each exo vert, find the matching cub vert
    1856         [ #  # ]:          0 :     for( int i = 0; i < numberNodes_loading; ++i )
    1857                 :            :     {
    1858         [ #  # ]:          0 :         int exo_id = ptr[i];
    1859 [ #  # ][ #  # ]:          0 :         CartVect exo_coords( orig_coords[0][i], orig_coords[1][i], orig_coords[2][i] );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1860                 :          0 :         EntityHandle cub_vert = 0;
    1861                 :          0 :         bool found_match      = false;
    1862                 :            : 
    1863                 :            :         // By id
    1864                 :            :         if( match_node_ids )
    1865                 :            :         {
    1866         [ #  # ]:          0 :             std::map< int, EntityHandle >::iterator i_iter;
    1867         [ #  # ]:          0 :             i_iter = cub_verts_id_map.find( exo_id );
    1868 [ #  # ][ #  # ]:          0 :             if( i_iter != cub_verts_id_map.end() )
    1869                 :            :             {
    1870                 :          0 :                 found_match = true;
    1871         [ #  # ]:          0 :                 cub_vert    = i_iter->second;
    1872                 :            :             }
    1873                 :            : 
    1874                 :            :             // By proximity
    1875                 :            :         }
    1876                 :            :         else
    1877                 :            :         {
    1878                 :            :             // The MAX_NODE_DIST is the farthest distance to  search for a node.
    1879                 :            :             // For the 1/12th symmetry 85 pin model, the max node dist could not be less
    1880                 :            :             // than 1e-1 (March 26, 2010).
    1881                 :            :             const double MAX_NODE_DIST = 1e-1;
    1882                 :            : 
    1883                 :            :             std::vector< EntityHandle > leaves;
    1884                 :            :             double min_dist = MAX_NODE_DIST;
    1885                 :            :             rval            = kdtree.distance_search( exo_coords.array(), MAX_NODE_DIST, leaves );
    1886                 :            :             if( MB_SUCCESS != rval ) return rval;
    1887                 :            :             for( std::vector< EntityHandle >::const_iterator j = leaves.begin(); j != leaves.end(); ++j )
    1888                 :            :             {
    1889                 :            :                 std::vector< EntityHandle > leaf_verts;
    1890                 :            :                 rval = mdbImpl->get_entities_by_type( *j, MBVERTEX, leaf_verts );
    1891                 :            :                 if( MB_SUCCESS != rval ) return rval;
    1892                 :            :                 for( std::vector< EntityHandle >::const_iterator k = leaf_verts.begin(); k != leaf_verts.end(); ++k )
    1893                 :            :                 {
    1894                 :            :                     CartVect orig_cub_coords, difference;
    1895                 :            :                     rval = mdbImpl->get_coords( &( *k ), 1, orig_cub_coords.array() );
    1896                 :            :                     if( MB_SUCCESS != rval ) return rval;
    1897                 :            :                     difference  = orig_cub_coords - exo_coords;
    1898                 :            :                     double dist = difference.length();
    1899                 :            :                     if( dist < min_dist )
    1900                 :            :                     {
    1901                 :            :                         min_dist = dist;
    1902                 :            :                         cub_vert = *k;
    1903                 :            :                     }
    1904                 :            :                 }
    1905                 :            :             }
    1906                 :            :             if( 0 != cub_vert ) found_match = true;
    1907                 :            :         }
    1908                 :            : 
    1909                 :            :         // If a match is found, update it with the deformed coords from the exo file.
    1910         [ #  # ]:          0 :         if( found_match )
    1911                 :            :         {
    1912         [ #  # ]:          0 :             CartVect updated_exo_coords;
    1913 [ #  # ][ #  # ]:          0 :             matched_cub_vert_id_map.insert( std::pair< int, EntityHandle >( exo_id, cub_vert ) );
    1914 [ #  # ][ #  # ]:          0 :             updated_exo_coords[0] = orig_coords[0][i] + deformed_arrays[0][i];
         [ #  # ][ #  # ]
                 [ #  # ]
    1915 [ #  # ][ #  # ]:          0 :             updated_exo_coords[1] = orig_coords[1][i] + deformed_arrays[1][i];
         [ #  # ][ #  # ]
                 [ #  # ]
    1916 [ #  # ][ #  # ]:          0 :             if( numberDimensions_loading == 3 ) updated_exo_coords[2] = orig_coords[2][i] + deformed_arrays[2][i];
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1917 [ #  # ][ #  # ]:          0 :             rval = mdbImpl->set_coords( &cub_vert, 1, updated_exo_coords.array() );
    1918         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
    1919                 :          0 :             ++found;
    1920                 :            :             double magnitude =
    1921 [ #  # ][ #  # ]:          0 :                 sqrt( deformed_arrays[0][i] * deformed_arrays[0][i] + deformed_arrays[1][i] * deformed_arrays[1][i] +
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1922 [ #  # ][ #  # ]:          0 :                       deformed_arrays[2][i] * deformed_arrays[2][i] );
         [ #  # ][ #  # ]
    1923         [ #  # ]:          0 :             if( magnitude > max_magnitude ) max_magnitude = magnitude;
    1924                 :          0 :             average_magnitude += magnitude;
    1925                 :            :         }
    1926                 :            :         else
    1927                 :            :         {
    1928                 :          0 :             ++lost;
    1929 [ #  # ][ #  # ]:          0 :             std::cout << "cannot match exo node " << exo_id << " " << exo_coords << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
    1930                 :            :         }
    1931                 :            :     }
    1932                 :            : 
    1933                 :            :     // Exo verts that could not be matched have already been printed. Now print the
    1934                 :            :     // cub verts that could not be matched.
    1935 [ #  # ][ #  # ]:          0 :     if( matched_cub_vert_id_map.size() < cub_verts.size() )
    1936                 :            :     {
    1937         [ #  # ]:          0 :         Range unmatched_cub_verts = cub_verts;
    1938 [ #  # ][ #  # ]:          0 :         for( std::map< int, EntityHandle >::const_iterator i = matched_cub_vert_id_map.begin();
         [ #  # ][ #  # ]
    1939         [ #  # ]:          0 :              i != matched_cub_vert_id_map.end(); ++i )
    1940                 :            :         {
    1941 [ #  # ][ #  # ]:          0 :             unmatched_cub_verts.erase( i->second );
    1942                 :            :         }
    1943 [ #  # ][ #  # ]:          0 :         for( Range::const_iterator i = unmatched_cub_verts.begin(); i != unmatched_cub_verts.end(); ++i )
         [ #  # ][ #  # ]
                 [ #  # ]
    1944                 :            :         {
    1945                 :            :             int cub_id;
    1946 [ #  # ][ #  # ]:          0 :             rval = mdbImpl->tag_get_data( mGlobalIdTag, &( *i ), 1, &cub_id );
    1947         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
    1948         [ #  # ]:          0 :             CartVect cub_coords;
    1949 [ #  # ][ #  # ]:          0 :             rval = mdbImpl->get_coords( &( *i ), 1, cub_coords.array() );
                 [ #  # ]
    1950         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
    1951 [ #  # ][ #  # ]:          0 :             std::cout << "cannot match cub node " << cub_id << " " << cub_coords << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
    1952                 :            :         }
    1953 [ #  # ][ #  # ]:          0 :         std::cout << "  " << unmatched_cub_verts.size() << " nodes from the cub file could not be matched."
         [ #  # ][ #  # ]
    1954 [ #  # ][ #  # ]:          0 :                   << std::endl;
    1955                 :            :     }
    1956                 :            : 
    1957                 :            :     // Summarize statistics
    1958 [ #  # ][ #  # ]:          0 :     std::cout << "  " << found << " nodes from the exodus file were matched in the cub_file_set ";
                 [ #  # ]
    1959 [ #  # ][ #  # ]:          0 :     if( match_node_ids ) { std::cout << "by id." << std::endl; }
    1960                 :            :     else
    1961                 :            :     {
    1962                 :            :         std::cout << "by proximity." << std::endl;
    1963                 :            :     }
    1964                 :            : 
    1965                 :            :     // Fail if all of the nodes could not be matched.
    1966         [ #  # ]:          0 :     if( 0 != lost )
    1967                 :            :     {
    1968 [ #  # ][ #  # ]:          0 :         std::cout << "Error:  " << lost << " nodes from the exodus file could not be matched." << std::endl;
         [ #  # ][ #  # ]
    1969                 :            :         // return MB_FAILURE;
    1970                 :            :     }
    1971 [ #  # ][ #  # ]:          0 :     std::cout << "  maximum node displacement magnitude: " << max_magnitude << " cm" << std::endl;
         [ #  # ][ #  # ]
    1972 [ #  # ][ #  # ]:          0 :     std::cout << "  average node displacement magnitude: " << average_magnitude / found << " cm" << std::endl;
         [ #  # ][ #  # ]
    1973                 :            : 
    1974                 :            :     // *******************************************************************
    1975                 :            :     // Remove dead elements from the MOAB instance.
    1976                 :            :     // *******************************************************************
    1977                 :            : 
    1978                 :            :     // How many element variables are in the file?
    1979                 :            :     int n_elem_var;
    1980 [ #  # ][ #  # ]:          0 :     GET_DIM( ncdim, "num_elem_var", n_elem_var );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1981                 :            : 
    1982                 :            :     // Get element variable names
    1983                 :          0 :     varid       = -1;
    1984         [ #  # ]:          0 :     int cstatus = nc_inq_varid( ncFile, "name_elem_var", &varid );
    1985         [ #  # ]:          0 :     std::vector< char > names_memory( n_elem_var * max_str_length );
    1986         [ #  # ]:          0 :     std::vector< char* > names( n_elem_var );
    1987         [ #  # ]:          0 :     for( int i = 0; i < n_elem_var; ++i )
    1988 [ #  # ][ #  # ]:          0 :         names[i] = &names_memory[i * max_str_length];
    1989 [ #  # ][ #  # ]:          0 :     if( cstatus != NC_NOERR || varid == -1 )
    1990                 :            :     {
    1991 [ #  # ][ #  # ]:          0 :         std::cout << "ReadNCDF: name_elem_var does not exist" << std::endl;
    1992                 :          0 :         return MB_FAILURE;
    1993                 :            :     }
    1994 [ #  # ][ #  # ]:          0 :     int status = nc_get_var_text( ncFile, varid, &names_memory[0] );
    1995 [ #  # ][ #  # ]:          0 :     if( NC_NOERR != status ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF: Problem getting element variable names" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1996                 :            : 
    1997                 :            :     // Is one of the element variable names "death_status"? If so, get its index
    1998                 :            :     // in the element variable array.
    1999                 :            :     int death_index;
    2000                 :          0 :     bool found_death_index = false;
    2001         [ #  # ]:          0 :     for( int i = 0; i < n_elem_var; ++i )
    2002                 :            :     {
    2003 [ #  # ][ #  # ]:          0 :         std::string temp( names[i] );
    2004         [ #  # ]:          0 :         std::string::size_type pos0 = temp.find( "death_status" );
    2005         [ #  # ]:          0 :         std::string::size_type pos1 = temp.find( "Death_Status" );
    2006         [ #  # ]:          0 :         std::string::size_type pos2 = temp.find( "DEATH_STATUS" );
    2007 [ #  # ][ #  # ]:          0 :         if( std::string::npos != pos0 || std::string::npos != pos1 || std::string::npos != pos2 )
                 [ #  # ]
    2008                 :            :         {
    2009                 :          0 :             found_death_index = true;
    2010                 :          0 :             death_index       = i + 1;  // NetCDF variables start with 1
    2011         [ #  # ]:          0 :             break;
    2012                 :            :         }
    2013                 :          0 :     }
    2014 [ #  # ][ #  # ]:          0 :     if( !found_death_index ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF: Problem getting index of death_status variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2015                 :            : 
    2016                 :            :     // The exodus header has already been read. This contains the number of element
    2017                 :            :     // blocks.
    2018                 :            : 
    2019                 :            :     // Dead elements are listed by block. Read the block headers to determine how
    2020                 :            :     // many elements are in each block.
    2021         [ #  # ]:          0 :     rval = read_block_headers( blocks_to_load, num_blocks );
    2022 [ #  # ][ #  # ]:          0 :     if( MB_FAILURE == rval ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF: Problem reading block headers" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2023                 :            : 
    2024                 :            :     // Dead elements from the Exodus file can be located in the cub_file_set by id
    2025                 :            :     // or by connectivity. Currently, finding elements by id requires careful book
    2026                 :            :     // keeping when constructing the model in Cubit. To avoid this, one can match
    2027                 :            :     // elements by connectivity instead.
    2028                 :          0 :     const bool match_elems_by_connectivity = true;
    2029                 :            : 
    2030                 :            :     // Get the element id map. The ids in the map are from the elements in the blocks.
    2031                 :            :     // elem_num_map(blk1 elem ids, blk2 elem ids, blk3 elem ids, ...)
    2032         [ #  # ]:          0 :     std::vector< int > elem_ids( numberNodes_loading );
    2033                 :            :     if( !match_elems_by_connectivity )
    2034                 :            :     {
    2035                 :            :         GET_1D_INT_VAR( "elem_num_map", varid, elem_ids );
    2036                 :            :         if( -1 == varid ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF: Problem getting element number map data" ); }
    2037                 :            :     }
    2038                 :            : 
    2039                 :            :     // For each block
    2040                 :          0 :     int first_elem_id_in_block = 0;
    2041                 :          0 :     int block_count            = 1;  // NetCDF variables start with 1
    2042                 :          0 :     int total_elems            = 0;
    2043                 :          0 :     int total_dead_elems       = 0;
    2044 [ #  # ][ #  # ]:          0 :     for( std::vector< ReadBlockData >::iterator i = blocksLoading.begin(); i != blocksLoading.end(); ++i )
                 [ #  # ]
    2045                 :            :     {
    2046                 :            :         // Get the ncdf connect variable
    2047         [ #  # ]:          0 :         std::string temp_string( "connect" );
    2048 [ #  # ][ #  # ]:          0 :         std::stringstream temp_ss;
                 [ #  # ]
    2049         [ #  # ]:          0 :         temp_ss << block_count;
    2050 [ #  # ][ #  # ]:          0 :         temp_string += temp_ss.str();
    2051         [ #  # ]:          0 :         temp_string += "\0";
    2052 [ #  # ][ #  # ]:          0 :         std::vector< int > ldims;
    2053 [ #  # ][ #  # ]:          0 :         GET_VAR( temp_string.c_str(), nc_var, ldims );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2054 [ #  # ][ #  # ]:          0 :         if( !nc_var ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting connect variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2055                 :            :         // The element type is an attribute of the connectivity variable
    2056                 :            :         nc_type att_type;
    2057                 :            :         size_t att_len;
    2058         [ #  # ]:          0 :         fail = nc_inq_att( ncFile, nc_var, "elem_type", &att_type, &att_len );
    2059 [ #  # ][ #  # ]:          0 :         if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting elem type attribute" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2060 [ #  # ][ #  # ]:          0 :         std::vector< char > dum_str( att_len + 1 );
    2061 [ #  # ][ #  # ]:          0 :         fail = nc_get_att_text( ncFile, nc_var, "elem_type", &dum_str[0] );
    2062 [ #  # ][ #  # ]:          0 :         if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting elem type" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2063 [ #  # ][ #  # ]:          0 :         ExoIIElementType elem_type = ExoIIUtil::static_element_name_to_type( &dum_str[0] );
    2064         [ #  # ]:          0 :         ( *i ).elemType            = elem_type;
    2065         [ #  # ]:          0 :         const EntityType mb_type   = ExoIIUtil::ExoIIElementMBEntity[( *i ).elemType];
    2066                 :            : 
    2067                 :            :         // Get the number of nodes per element
    2068         [ #  # ]:          0 :         unsigned int nodes_per_element = ExoIIUtil::VerticesPerElement[( *i ).elemType];
    2069                 :            : 
    2070                 :            :         // Read the connectivity into that memory.
    2071                 :            :         // int exo_conn[i->numElements][nodes_per_element];
    2072 [ #  # ][ #  # ]:          0 :         int* exo_conn = new int[i->numElements * nodes_per_element];
                 [ #  # ]
    2073                 :            :         // NcBool status = temp_var->get(&exo_conn[0][0], i->numElements, nodes_per_element);
    2074                 :          0 :         size_t lstart[2] = { 0, 0 }, lcount[2];
    2075         [ #  # ]:          0 :         lcount[0]        = i->numElements;
    2076                 :          0 :         lcount[1]        = nodes_per_element;
    2077         [ #  # ]:          0 :         fail             = nc_get_vara_int( ncFile, nc_var, lstart, lcount, exo_conn );
    2078         [ #  # ]:          0 :         if( NC_NOERR != fail )
    2079                 :            :         {
    2080         [ #  # ]:          0 :             delete[] exo_conn;
    2081 [ #  # ][ #  # ]:          0 :             MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting connectivity" );
         [ #  # ][ #  # ]
                 [ #  # ]
    2082                 :            :         }
    2083                 :            : 
    2084                 :            :         // Get the death_status at the correct time step.
    2085 [ #  # ][ #  # ]:          0 :         std::vector< double > death_status( i->numElements );  // It seems wrong, but it uses doubles
                 [ #  # ]
    2086 [ #  # ][ #  # ]:          0 :         std::string array_name( "vals_elem_var" );
    2087 [ #  # ][ #  # ]:          0 :         temp_ss.str( "" );  // stringstream won't clear by temp.clear()
    2088         [ #  # ]:          0 :         temp_ss << death_index;
    2089 [ #  # ][ #  # ]:          0 :         array_name += temp_ss.str();
    2090         [ #  # ]:          0 :         array_name += "eb";
    2091 [ #  # ][ #  # ]:          0 :         temp_ss.str( "" );  // stringstream won't clear by temp.clear()
    2092         [ #  # ]:          0 :         temp_ss << block_count;
    2093 [ #  # ][ #  # ]:          0 :         array_name += temp_ss.str();
    2094         [ #  # ]:          0 :         array_name += "\0";
    2095 [ #  # ][ #  # ]:          0 :         GET_VAR( array_name.c_str(), nc_var, ldims );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2096 [ #  # ][ #  # ]:          0 :         if( !nc_var ) { MB_SET_ERR( MB_FAILURE, "ReadNCDF:: Problem getting death status variable" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2097                 :          0 :         lstart[0] = time_step - 1;
    2098                 :          0 :         lstart[1] = 0;
    2099                 :          0 :         lcount[0] = 1;
    2100         [ #  # ]:          0 :         lcount[1] = i->numElements;
    2101 [ #  # ][ #  # ]:          0 :         status    = nc_get_vara_double( ncFile, nc_var, lstart, lcount, &death_status[0] );
    2102         [ #  # ]:          0 :         if( NC_NOERR != status )
    2103                 :            :         {
    2104         [ #  # ]:          0 :             delete[] exo_conn;
    2105 [ #  # ][ #  # ]:          0 :             MB_SET_ERR( MB_FAILURE, "ReadNCDF: Problem setting time step for death_status" );
         [ #  # ][ #  # ]
                 [ #  # ]
    2106                 :            :         }
    2107                 :            : 
    2108                 :            :         // Look for dead elements. If there is too many dead elements and this starts
    2109                 :            :         // to take too long, I should put the elems in a kd-tree for more efficient
    2110                 :            :         // searching. Alternatively I could get the exo connectivity and match nodes.
    2111                 :          0 :         int dead_elem_counter = 0, missing_elem_counter = 0;
    2112 [ #  # ][ #  # ]:          0 :         for( int j = 0; j < i->numElements; ++j )
    2113                 :            :         {
    2114 [ #  # ][ #  # ]:          0 :             if( 1 != death_status[j] )
    2115                 :            :             {
    2116 [ #  # ][ #  # ]:          0 :                 Range cub_elem, cub_nodes;
                 [ #  # ]
    2117                 :            :                 if( match_elems_by_connectivity )
    2118                 :            :                 {
    2119                 :            :                     // Get exodus nodes for the element
    2120         [ #  # ]:          0 :                     std::vector< int > elem_conn( nodes_per_element );
    2121         [ #  # ]:          0 :                     for( unsigned int k = 0; k < nodes_per_element; ++k )
    2122                 :            :                     {
    2123                 :            :                         // elem_conn[k] = exo_conn[j][k];
    2124         [ #  # ]:          0 :                         elem_conn[k] = exo_conn[j * nodes_per_element + k];
    2125                 :            :                     }
    2126                 :            :                     // Get the ids of the nodes (assume we are matching by id)
    2127                 :            :                     // Remember that the exodus array locations start with 1 (not 0).
    2128 [ #  # ][ #  # ]:          0 :                     std::vector< int > elem_conn_node_ids( nodes_per_element );
    2129         [ #  # ]:          0 :                     for( unsigned int k = 0; k < nodes_per_element; ++k )
    2130                 :            :                     {
    2131 [ #  # ][ #  # ]:          0 :                         elem_conn_node_ids[k] = ptr[elem_conn[k] - 1];
                 [ #  # ]
    2132                 :            :                     }
    2133                 :            :                     // Get the cub_file_set nodes by id
    2134                 :            :                     // The map is a log search and takes almost no time.
    2135                 :            :                     // MOAB's linear tag search takes 5-10 minutes.
    2136         [ #  # ]:          0 :                     for( unsigned int k = 0; k < nodes_per_element; ++k )
    2137                 :            :                     {
    2138         [ #  # ]:          0 :                         std::map< int, EntityHandle >::iterator k_iter;
    2139 [ #  # ][ #  # ]:          0 :                         k_iter = matched_cub_vert_id_map.find( elem_conn_node_ids[k] );
    2140                 :            : 
    2141 [ #  # ][ #  # ]:          0 :                         if( k_iter == matched_cub_vert_id_map.end() )
    2142                 :            :                         {
    2143 [ #  # ][ #  # ]:          0 :                             std::cout << "ReadNCDF: Found no cub node with id=" << elem_conn_node_ids[k]
                 [ #  # ]
    2144 [ #  # ][ #  # ]:          0 :                                       << ", but expected to find only 1." << std::endl;
    2145                 :          0 :                             break;
    2146                 :            :                         }
    2147 [ #  # ][ #  # ]:          0 :                         cub_nodes.insert( k_iter->second );
    2148                 :            :                     }
    2149                 :            : 
    2150 [ #  # ][ #  # ]:          0 :                     if( nodes_per_element != cub_nodes.size() )
    2151                 :            :                     {
    2152 [ #  # ][ #  # ]:          0 :                         std::cout << "ReadNCDF: nodes_per_elemenet != cub_nodes.size()" << std::endl;
    2153         [ #  # ]:          0 :                         delete[] exo_conn;
    2154                 :          0 :                         return MB_INVALID_SIZE;
    2155                 :            :                     }
    2156                 :            : 
    2157                 :            :                     // Get the cub_file_set element with the same nodes
    2158         [ #  # ]:          0 :                     int to_dim = CN::Dimension( mb_type );
    2159         [ #  # ]:          0 :                     rval       = mdbImpl->get_adjacencies( cub_nodes, to_dim, false, cub_elem );
    2160         [ #  # ]:          0 :                     if( MB_SUCCESS != rval )
    2161                 :            :                     {
    2162 [ #  # ][ #  # ]:          0 :                         std::cout << "ReadNCDF: could not get dead cub element" << std::endl;
    2163         [ #  # ]:          0 :                         delete[] exo_conn;
    2164         [ #  # ]:          0 :                         return rval;
    2165                 :          0 :                     }
    2166                 :            : 
    2167                 :            :                     // Pronto/Presto renumbers elements, so matching cub and exo elements by
    2168                 :            :                     // id is not possible at this time.
    2169                 :            :                 }
    2170                 :            :                 else
    2171                 :            :                 {
    2172                 :            :                     // Get dead element's id
    2173                 :            :                     int elem_id = elem_ids[first_elem_id_in_block + j];
    2174                 :            :                     void* id[]  = { &elem_id };
    2175                 :            :                     // Get the element by id
    2176                 :            :                     rval = mdbImpl->get_entities_by_type_and_tag( cub_file_set, mb_type, &mGlobalIdTag, id, 1, cub_elem,
    2177                 :            :                                                                   Interface::INTERSECT );
    2178                 :            :                     if( MB_SUCCESS != rval )
    2179                 :            :                     {
    2180                 :            :                         delete[] exo_conn;
    2181                 :            :                         return rval;
    2182                 :            :                     }
    2183                 :            :                 }
    2184                 :            : 
    2185 [ #  # ][ #  # ]:          0 :                 if( 1 == cub_elem.size() )
    2186                 :            :                 {
    2187                 :            :                     // Delete the dead element from the cub file. It will be removed from sets
    2188                 :            :                     // ONLY if they are tracking meshsets.
    2189         [ #  # ]:          0 :                     rval = mdbImpl->remove_entities( cub_file_set, cub_elem );
    2190         [ #  # ]:          0 :                     if( MB_SUCCESS != rval )
    2191                 :            :                     {
    2192         [ #  # ]:          0 :                         delete[] exo_conn;
    2193                 :          0 :                         return rval;
    2194                 :            :                     }
    2195         [ #  # ]:          0 :                     rval = mdbImpl->delete_entities( cub_elem );
    2196         [ #  # ]:          0 :                     if( MB_SUCCESS != rval )
    2197                 :            :                     {
    2198         [ #  # ]:          0 :                         delete[] exo_conn;
    2199                 :          0 :                         return rval;
    2200                 :            :                     }
    2201                 :            :                 }
    2202                 :            :                 else
    2203                 :            :                 {
    2204 [ #  # ][ #  # ]:          0 :                     std::cout << "ReadNCDF: Should have found 1 element with  type=" << mb_type
    2205 [ #  # ][ #  # ]:          0 :                               << " in cub_file_set, but instead found " << cub_elem.size() << std::endl;
         [ #  # ][ #  # ]
    2206         [ #  # ]:          0 :                     rval = mdbImpl->list_entities( cub_nodes );
    2207                 :          0 :                     ++missing_elem_counter;
    2208         [ #  # ]:          0 :                     delete[] exo_conn;
    2209                 :          0 :                     return MB_FAILURE;
    2210                 :            :                 }
    2211         [ #  # ]:          0 :                 ++dead_elem_counter;
    2212                 :            :             }
    2213                 :            :         }
    2214                 :            :         // Print some statistics
    2215 [ #  # ][ #  # ]:          0 :         temp_ss.str( "" );
    2216 [ #  # ][ #  # ]:          0 :         temp_ss << i->blockId;
    2217                 :          0 :         total_dead_elems += dead_elem_counter;
    2218         [ #  # ]:          0 :         total_elems += i->numElements;
    2219 [ #  # ][ #  # ]:          0 :         std::cout << "  Block " << temp_ss.str() << " has " << dead_elem_counter << "/" << i->numElements
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2220 [ #  # ][ #  # ]:          0 :                   << " dead elements." << std::endl;
    2221         [ #  # ]:          0 :         if( 0 != missing_elem_counter )
    2222                 :            :         {
    2223 [ #  # ][ #  # ]:          0 :             std::cout << "    " << missing_elem_counter
    2224 [ #  # ][ #  # ]:          0 :                       << " dead elements in this block were not found in the cub_file_set." << std::endl;
    2225                 :            :         }
    2226                 :            : 
    2227                 :            :         // Advance the pointers into element ids and block_count. Memory cleanup.
    2228         [ #  # ]:          0 :         first_elem_id_in_block += i->numElements;
    2229                 :          0 :         ++block_count;
    2230 [ #  # ][ #  # ]:          0 :         delete[] exo_conn;
    2231                 :          0 :     }
    2232                 :            : 
    2233 [ #  # ][ #  # ]:          0 :     std::cout << " Total: " << total_dead_elems << "/" << total_elems << " dead elements." << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2234                 :            : 
    2235                 :            :     // Close the file
    2236         [ #  # ]:          0 :     fail = nc_close( ncFile );
    2237 [ #  # ][ #  # ]:          0 :     if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "Trouble closing file" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2238                 :            : 
    2239                 :          0 :     ncFile = 0;
    2240                 :          0 :     return MB_SUCCESS;
    2241                 :            : }
    2242                 :            : 
    2243                 :          0 : void ReadNCDF::tokenize( const std::string& str, std::vector< std::string >& tokens, const char* delimiters )
    2244                 :            : {
    2245                 :          0 :     std::string::size_type last = str.find_first_not_of( delimiters, 0 );
    2246                 :          0 :     std::string::size_type pos  = str.find_first_of( delimiters, last );
    2247 [ #  # ][ #  # ]:          0 :     while( std::string::npos != pos && std::string::npos != last )
    2248                 :            :     {
    2249         [ #  # ]:          0 :         tokens.push_back( str.substr( last, pos - last ) );
    2250                 :          0 :         last = str.find_first_not_of( delimiters, pos );
    2251                 :          0 :         pos  = str.find_first_of( delimiters, last );
    2252         [ #  # ]:          0 :         if( std::string::npos == pos ) pos = str.size();
    2253                 :            :     }
    2254                 :          0 : }
    2255                 :            : 
    2256 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11