LCOV - code coverage report
Current view: top level - src/io - ReadMCNP5.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 67 454 14.8 %
Date: 2020-12-16 07:07:30 Functions: 9 22 40.9 %
Branches: 37 922 4.0 %

           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                 :            : #include "ReadMCNP5.hpp"
      17                 :            : #include "moab/Interface.hpp"
      18                 :            : #include "moab/ReadUtilIface.hpp"
      19                 :            : #include "Internals.hpp"  // For MB_START_ID
      20                 :            : #include "moab/Range.hpp"
      21                 :            : #include "moab/FileOptions.hpp"
      22                 :            : #include "moab/Util.hpp"
      23                 :            : 
      24                 :            : #include <iostream>
      25                 :            : #include <sstream>
      26                 :            : #include <fstream>
      27                 :            : #include <vector>
      28                 :            : #include <cstdlib>
      29                 :            : #include <cmath>
      30                 :            : #include <cassert>
      31                 :            : 
      32                 :            : namespace moab
      33                 :            : {
      34                 :            : 
      35                 :            : // Parameters
      36                 :            : const double ReadMCNP5::PI   = 3.141592653589793;
      37                 :            : const double ReadMCNP5::C2PI = 0.1591549430918954;
      38                 :            : const double ReadMCNP5::CPI  = 0.3183098861837907;
      39                 :            : 
      40                 :          1 : ReaderIface* ReadMCNP5::factory( Interface* iface )
      41                 :            : {
      42         [ +  - ]:          1 :     return new ReadMCNP5( iface );
      43                 :            : }
      44                 :            : 
      45                 :            : // Constructor
      46                 :          2 : ReadMCNP5::ReadMCNP5( Interface* impl ) : MBI( impl ), fileIDTag( NULL ), nodeId( 0 ), elemId( 0 )
      47                 :            : {
      48         [ -  + ]:          1 :     assert( NULL != impl );
      49         [ +  - ]:          1 :     MBI->query_interface( readMeshIface );
      50         [ -  + ]:          1 :     assert( NULL != readMeshIface );
      51                 :          1 : }
      52                 :            : 
      53                 :            : // Destructor
      54                 :          3 : ReadMCNP5::~ReadMCNP5()
      55                 :            : {
      56         [ +  - ]:          1 :     if( readMeshIface )
      57                 :            :     {
      58                 :          1 :         MBI->release_interface( readMeshIface );
      59                 :          1 :         readMeshIface = 0;
      60                 :            :     }
      61         [ -  + ]:          2 : }
      62                 :            : 
      63                 :          0 : ErrorCode ReadMCNP5::read_tag_values( const char* /* file_name */, const char* /* tag_name */,
      64                 :            :                                       const FileOptions& /* opts */, std::vector< int >& /* tag_values_out */,
      65                 :            :                                       const SubsetList* /* subset_list */ )
      66                 :            : {
      67                 :          0 :     return MB_NOT_IMPLEMENTED;
      68                 :            : }
      69                 :            : 
      70                 :            : // Load the file as called by the Interface function
      71                 :          1 : ErrorCode ReadMCNP5::load_file( const char* filename, const EntityHandle* input_meshset, const FileOptions& options,
      72                 :            :                                 const ReaderIface::SubsetList* subset_list, const Tag* file_id_tag )
      73                 :            : {
      74                 :            :     // At this time there is no support for reading a subset of the file
      75 [ -  + ][ #  # ]:          1 :     if( subset_list ) { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for meshtal" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      76                 :            : 
      77                 :          1 :     nodeId = elemId = 0;
      78                 :          1 :     fileIDTag       = file_id_tag;
      79                 :            : 
      80                 :            :     // Average several meshtal files if the AVERAGE_TALLY option is given.
      81                 :            :     // In this case, the integer value is the number of files to average.
      82                 :            :     // If averaging, the filename passed to load_file is assumed to be the
      83                 :            :     // root filename. The files are indexed as "root_filename""index".meshtal.
      84                 :            :     // Indices start with 1.
      85                 :            :     int n_files;
      86                 :          1 :     bool average = false;
      87                 :            :     ErrorCode result;
      88 [ +  - ][ -  + ]:          1 :     if( MB_SUCCESS == options.get_int_option( "AVERAGE_TALLY", n_files ) )
      89                 :            :     {
      90                 :            :         // Read the first file (but do not average -> can't average a single file)
      91         [ #  # ]:          0 :         result = load_one_file( filename, input_meshset, options, average );
      92         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
      93                 :            : 
      94                 :            :         // Get the root filename
      95         [ #  # ]:          0 :         std::string root_filename( filename );
      96                 :          0 :         int length = root_filename.length();
      97         [ #  # ]:          0 :         root_filename.erase( length - sizeof( ".meshtal" ) );
      98                 :            : 
      99                 :            :         // Average the first file with the rest of the files
     100                 :          0 :         average = true;
     101 [ #  # ][ #  # ]:          0 :         for( int i = 2; i <= n_files; i++ )
     102                 :            :         {
     103 [ #  # ][ #  # ]:          0 :             std::stringstream index;
     104         [ #  # ]:          0 :             index << i;
     105 [ #  # ][ #  # ]:          0 :             std::string subsequent_filename = root_filename + index.str() + ".meshtal";
         [ #  # ][ #  # ]
     106         [ #  # ]:          0 :             result = load_one_file( subsequent_filename.c_str(), input_meshset, options, average );
     107 [ #  # ][ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     108                 :          0 :         }
     109                 :            : 
     110                 :            :         // If not averaging, read a single file
     111                 :            :     }
     112                 :            :     else
     113                 :            :     {
     114         [ +  - ]:          1 :         result = load_one_file( filename, input_meshset, options, average );
     115         [ +  - ]:          1 :         if( MB_SUCCESS != result ) return result;
     116                 :            :     }
     117                 :            : 
     118                 :          1 :     return MB_SUCCESS;
     119                 :            : }
     120                 :            : 
     121                 :            : // This actually reads the file. It creates the mesh elements unless
     122                 :            : // the file is being averaged with a pre-existing mesh.
     123                 :          1 : ErrorCode ReadMCNP5::load_one_file( const char* fname, const EntityHandle* input_meshset, const FileOptions& options,
     124                 :            :                                     const bool average )
     125                 :            : {
     126                 :          1 :     bool debug = false;
     127 [ -  + ][ #  # ]:          1 :     if( debug ) std::cout << "begin ReadMCNP5::load_one_file" << std::endl;
                 [ #  # ]
     128                 :            : 
     129                 :            :     ErrorCode result;
     130         [ +  - ]:          1 :     std::fstream file;
     131         [ +  - ]:          1 :     file.open( fname, std::fstream::in );
     132                 :            :     char line[10000];
     133                 :            : 
     134                 :            :     // Create tags
     135                 :            :     Tag date_and_time_tag, title_tag, nps_tag, tally_number_tag, tally_comment_tag, tally_particle_tag,
     136                 :            :         tally_coord_sys_tag, tally_tag, error_tag;
     137                 :            : 
     138                 :            :     result = create_tags( date_and_time_tag, title_tag, nps_tag, tally_number_tag, tally_comment_tag,
     139         [ +  - ]:          1 :                           tally_particle_tag, tally_coord_sys_tag, tally_tag, error_tag );
     140         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
     141                 :            : 
     142                 :            :     // ******************************************************************
     143                 :            :     // This info exists only at the top of each meshtal file
     144                 :            :     // ******************************************************************
     145                 :            : 
     146                 :            :     // Define characteristics of the entire file
     147                 :          1 :     char date_and_time[100] = "";
     148                 :          1 :     char title[100]         = "";
     149                 :            :     // This file's number of particles
     150                 :            :     unsigned long int nps;
     151                 :            :     // Sum of this file's and existing file's nps for averaging
     152                 :            :     unsigned long int new_nps;
     153                 :            : 
     154                 :            :     // Read the file header
     155         [ +  - ]:          1 :     result = read_file_header( file, debug, date_and_time, title, nps );
     156         [ +  - ]:          1 :     if( MB_SUCCESS != result ) return result;
     157                 :            : 
     158                 :            :     // Blank line
     159         [ #  # ]:          0 :     file.getline( line, 10000 );
     160                 :            : 
     161                 :            :     // Everything stored in the file being read will be in the input_meshset.
     162                 :            :     // If this is being saved in MOAB, set header tags
     163 [ #  # ][ #  # ]:          0 :     if( !average && 0 != input_meshset )
     164                 :            :     {
     165         [ #  # ]:          0 :         result = set_header_tags( *input_meshset, date_and_time, title, nps, date_and_time_tag, title_tag, nps_tag );
     166         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     167                 :            :     }
     168                 :            : 
     169                 :            :     // ******************************************************************
     170                 :            :     // This info is repeated for each tally in the meshtal file.
     171                 :            :     // ******************************************************************
     172                 :            : 
     173                 :            :     // If averaging, nps will hold the sum of particles simulated in both tallies.
     174 [ #  # ][ #  # ]:          0 :     while( !file.eof() )
     175                 :            :     {
     176                 :            :         // Define characteristics of this tally
     177                 :            :         unsigned int tally_number;
     178                 :          0 :         char tally_comment[100] = "";
     179                 :            :         particle tally_particle;
     180                 :            :         coordinate_system tally_coord_sys;
     181 [ #  # ][ #  # ]:          0 :         std::vector< double > planes[3];
           [ #  #  #  # ]
     182                 :            :         unsigned int n_chopped_x0_planes;
     183                 :            :         unsigned int n_chopped_x2_planes;
     184                 :            : 
     185                 :            :         // Read tally header
     186         [ #  # ]:          0 :         result = read_tally_header( file, debug, tally_number, tally_comment, tally_particle );
     187         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     188                 :            : 
     189                 :            :         // Blank line
     190         [ #  # ]:          0 :         file.getline( line, 10000 );
     191 [ #  # ][ #  # ]:          0 :         std::string l = line;
     192                 :            :         // if this string is present then skip the following blank line
     193 [ #  # ][ #  # ]:          0 :         if( std::string::npos != l.find( "This mesh tally is modified by a dose response function." ) )
     194         [ #  # ]:          0 :         { file.getline( line, 10000 ); }
     195                 :            : 
     196                 :            :         // Read mesh planes
     197         [ #  # ]:          0 :         result = read_mesh_planes( file, debug, planes, tally_coord_sys );
     198         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     199                 :            : 
     200                 :            :         // Get energy boundaries
     201         [ #  # ]:          0 :         file.getline( line, 10000 );
     202 [ #  # ][ #  # ]:          0 :         std::string a = line;
     203 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "Energy bin boundaries:=| " << a << std::endl;
         [ #  # ][ #  # ]
     204                 :            : 
     205                 :            :         // Blank
     206         [ #  # ]:          0 :         file.getline( line, 10000 );
     207                 :            : 
     208                 :            :         // Column headers
     209         [ #  # ]:          0 :         file.getline( line, 10000 );
     210                 :            : 
     211                 :            :         // If using cylindrical mesh, it may be necessary to chop off the last theta element.
     212                 :            :         // We chop off the last theta plane because the elements will be wrong and skew up
     213                 :            :         // the tree building code. This is
     214                 :            :         // because the hex elements are a linear approximation to the cylindrical elements.
     215                 :            :         // Chopping off the last plane is problem-dependent, and due to MCNP5's mandate
     216                 :            :         // that the cylindrical mesh must span 360 degrees.
     217 [ #  # ][ #  # ]:          0 :         if( CYLINDRICAL == tally_coord_sys && MB_SUCCESS == options.get_null_option( "REMOVE_LAST_AZIMUTHAL_PLANE" ) )
         [ #  # ][ #  # ]
     218                 :            :         {
     219         [ #  # ]:          0 :             planes[2].pop_back();
     220                 :          0 :             n_chopped_x2_planes = 1;
     221 [ #  # ][ #  # ]:          0 :             if( debug ) std::cout << "remove last cylindrical plane option found" << std::endl;
                 [ #  # ]
     222                 :            :         }
     223                 :            :         else
     224                 :            :         {
     225                 :          0 :             n_chopped_x2_planes = 0;
     226                 :            :         }
     227                 :            : 
     228                 :            :         // If using cylindrical mesh, it may be necessary to chop off the first radial element.
     229                 :            :         // These elements extend from the axis and often do not cover areas of interest. For
     230                 :            :         // example, if the mesh was meant to cover r=390-400, the first layer will go from
     231                 :            :         // 0-390 and serve as incorrect source elements for interpolation.
     232 [ #  # ][ #  # ]:          0 :         if( CYLINDRICAL == tally_coord_sys && MB_SUCCESS == options.get_null_option( "REMOVE_FIRST_RADIAL_PLANE" ) )
         [ #  # ][ #  # ]
     233                 :            :         {
     234                 :          0 :             std::vector< double >::iterator front = planes[0].begin();
     235         [ #  # ]:          0 :             planes[0].erase( front );
     236                 :          0 :             n_chopped_x0_planes = 1;
     237 [ #  # ][ #  # ]:          0 :             if( debug ) std::cout << "remove first radial plane option found" << std::endl;
                 [ #  # ]
     238                 :            :         }
     239                 :            :         else
     240                 :            :         {
     241                 :          0 :             n_chopped_x0_planes = 0;
     242                 :            :         }
     243                 :            : 
     244                 :            :         // Read the values and errors of each element from the file.
     245                 :            :         // Do not read values that are chopped off.
     246                 :          0 :         unsigned int n_elements = ( planes[0].size() - 1 ) * ( planes[1].size() - 1 ) * ( planes[2].size() - 1 );
     247 [ #  # ][ #  # ]:          0 :         double* values          = new double[n_elements];
     248 [ #  # ][ #  # ]:          0 :         double* errors          = new double[n_elements];
     249                 :            :         result = read_element_values_and_errors( file, debug, planes, n_chopped_x0_planes, n_chopped_x2_planes,
     250         [ #  # ]:          0 :                                                  tally_particle, values, errors );
     251         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     252                 :            : 
     253                 :            :         // Blank line
     254         [ #  # ]:          0 :         file.getline( line, 10000 );
     255                 :            : 
     256                 :            :         // ****************************************************************
     257                 :            :         // This tally has been read. If it is not being averaged, build tags,
     258                 :            :         // vertices and elements. If it is being averaged, average the data
     259                 :            :         // with a tally already existing in the MOAB instance.
     260                 :            :         // ****************************************************************
     261         [ #  # ]:          0 :         if( !average )
     262                 :            :         {
     263                 :            :             EntityHandle tally_meshset;
     264         [ #  # ]:          0 :             result = MBI->create_meshset( MESHSET_SET, tally_meshset );
     265         [ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     266                 :            : 
     267                 :            :             // Set tags on the tally
     268                 :            :             result = set_tally_tags( tally_meshset, tally_number, tally_comment, tally_particle, tally_coord_sys,
     269         [ #  # ]:          0 :                                      tally_number_tag, tally_comment_tag, tally_particle_tag, tally_coord_sys_tag );
     270         [ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     271                 :            : 
     272                 :            :             // The only info needed to build elements is the mesh plane boundaries.
     273                 :            :             // Build vertices...
     274                 :          0 :             EntityHandle start_vert = 0;
     275         [ #  # ]:          0 :             result                  = create_vertices( planes, debug, start_vert, tally_coord_sys, tally_meshset );
     276         [ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     277                 :            : 
     278                 :            :             // Build elements and tag them with tally values and errors, then add
     279                 :            :             // them to the tally_meshset.
     280                 :            :             result = create_elements( debug, planes, n_chopped_x0_planes, n_chopped_x2_planes, start_vert, values,
     281         [ #  # ]:          0 :                                       errors, tally_tag, error_tag, tally_meshset, tally_coord_sys );
     282         [ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     283                 :            : 
     284                 :            :             // Add this tally's meshset to the output meshset
     285 [ #  # ][ #  # ]:          0 :             if( debug ) std::cout << "not averaging tally" << std::endl;
                 [ #  # ]
     286                 :            : 
     287                 :            :             // Average the tally values, then delete stuff that was created
     288                 :            :         }
     289                 :            :         else
     290                 :            :         {
     291 [ #  # ][ #  # ]:          0 :             if( debug ) std::cout << "averaging tally" << std::endl;
                 [ #  # ]
     292                 :            :             result = average_with_existing_tally( debug, new_nps, nps, tally_number, tally_number_tag, nps_tag,
     293         [ #  # ]:          0 :                                                   tally_tag, error_tag, values, errors, n_elements );
     294         [ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     295                 :            :         }
     296                 :            : 
     297                 :            :         // Clean up
     298         [ #  # ]:          0 :         delete[] values;
     299 [ #  # ][ #  # ]:          0 :         delete[] errors;
     300         [ #  # ]:          0 :     }
     301                 :            : 
     302                 :            :     // If we are averaging, delete the remainder of this file's information.
     303                 :            :     // Add the new nps to the existing file's nps if we are averaging.
     304                 :            :     // This is calculated during every tally averaging but only used after the last one.
     305         [ #  # ]:          0 :     if( average )
     306                 :            :     {
     307         [ #  # ]:          0 :         Range matching_nps_sets;
     308         [ #  # ]:          0 :         result = MBI->get_entities_by_type_and_tag( 0, MBENTITYSET, &nps_tag, 0, 1, matching_nps_sets );
     309         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     310 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "number of matching nps meshsets=" << matching_nps_sets.size() << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
     311 [ #  # ][ #  # ]:          0 :         assert( 1 == matching_nps_sets.size() );
     312         [ #  # ]:          0 :         result = MBI->tag_set_data( nps_tag, matching_nps_sets, &new_nps );
     313 [ #  # ][ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     314                 :            : 
     315                 :            :         // If this file is not being averaged, return the output meshset.
     316                 :            :     }
     317                 :            : 
     318         [ #  # ]:          0 :     file.close();
     319         [ #  # ]:          1 :     return MB_SUCCESS;
     320                 :            : }
     321                 :            : 
     322                 :            : // create tags needed for this reader
     323                 :          1 : ErrorCode ReadMCNP5::create_tags( Tag& date_and_time_tag, Tag& title_tag, Tag& nps_tag, Tag& tally_number_tag,
     324                 :            :                                   Tag& tally_comment_tag, Tag& tally_particle_tag, Tag& tally_coord_sys_tag,
     325                 :            :                                   Tag& tally_tag, Tag& error_tag )
     326                 :            : {
     327                 :            :     ErrorCode result;
     328                 :            :     result = MBI->tag_get_handle( "DATE_AND_TIME_TAG", 100, MB_TYPE_OPAQUE, date_and_time_tag,
     329                 :          1 :                                   MB_TAG_SPARSE | MB_TAG_CREAT );
     330         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
     331                 :          1 :     result = MBI->tag_get_handle( "TITLE_TAG", 100, MB_TYPE_OPAQUE, title_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
     332         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
     333                 :            :     result = MBI->tag_get_handle( "NPS_TAG", sizeof( unsigned long int ), MB_TYPE_OPAQUE, nps_tag,
     334                 :          1 :                                   MB_TAG_SPARSE | MB_TAG_CREAT );
     335         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
     336                 :            :     result =
     337                 :          1 :         MBI->tag_get_handle( "TALLY_NUMBER_TAG", 1, MB_TYPE_INTEGER, tally_number_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
     338         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
     339                 :            :     result = MBI->tag_get_handle( "TALLY_COMMENT_TAG", 100, MB_TYPE_OPAQUE, tally_comment_tag,
     340                 :          1 :                                   MB_TAG_SPARSE | MB_TAG_CREAT );
     341         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
     342                 :            :     result = MBI->tag_get_handle( "TALLY_PARTICLE_TAG", sizeof( particle ), MB_TYPE_OPAQUE, tally_particle_tag,
     343                 :          1 :                                   MB_TAG_SPARSE | MB_TAG_CREAT );
     344         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
     345                 :            :     result = MBI->tag_get_handle( "TALLY_COORD_SYS_TAG", sizeof( coordinate_system ), MB_TYPE_OPAQUE,
     346                 :          1 :                                   tally_coord_sys_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
     347         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
     348                 :          1 :     result = MBI->tag_get_handle( "TALLY_TAG", 1, MB_TYPE_DOUBLE, tally_tag, MB_TAG_DENSE | MB_TAG_CREAT );
     349         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
     350                 :          1 :     result = MBI->tag_get_handle( "ERROR_TAG", 1, MB_TYPE_DOUBLE, error_tag, MB_TAG_DENSE | MB_TAG_CREAT );
     351         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
     352                 :            : 
     353                 :          1 :     return MB_SUCCESS;
     354                 :            : }
     355                 :            : 
     356                 :          1 : ErrorCode ReadMCNP5::read_file_header( std::fstream& file, bool debug, char date_and_time[100], char title[100],
     357                 :            :                                        unsigned long int& nps )
     358                 :            : {
     359                 :            :     // Get simulation date and time
     360                 :            :     // mcnp   version 5     ld=11242008  probid =  03/23/09 13:38:56
     361                 :            :     char line[100];
     362         [ +  - ]:          1 :     file.getline( line, 100 );
     363                 :          1 :     date_and_time = line;
     364 [ -  + ][ #  # ]:          1 :     if( debug ) std::cout << "date_and_time=| " << date_and_time << std::endl;
         [ #  # ][ #  # ]
     365                 :            : 
     366                 :            :     // Get simulation title
     367                 :            :     // iter Module 4
     368         [ +  - ]:          1 :     file.getline( line, 100 );
     369                 :          1 :     title = line;
     370 [ -  + ][ #  # ]:          1 :     if( debug ) std::cout << "title=| " << title << std::endl;
         [ #  # ][ #  # ]
     371                 :            : 
     372                 :            :     // Get number of histories
     373                 :            :     // Number of histories used for normalizing tallies =      50000000.00
     374         [ +  - ]:          1 :     file.getline( line, 100 );
     375         [ +  - ]:          1 :     std::string a            = line;
     376         [ +  - ]:          1 :     std::string::size_type b = a.find( "Number of histories used for normalizing tallies =" );
     377         [ -  + ]:          1 :     if( std::string::npos != b )
     378                 :            :     {
     379                 :            :         std::istringstream nps_ss(
     380 [ #  # ][ #  # ]:          0 :             a.substr( b + sizeof( "Number of histories used for normalizing tallies =" ), 100 ) );
     381         [ #  # ]:          0 :         nps_ss >> nps;
     382 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "nps=| " << nps << std::endl;
         [ #  # ][ #  # ]
     383                 :            :     }
     384                 :            :     else
     385                 :          1 :         return MB_FAILURE;
     386                 :            : 
     387                 :          1 :     return MB_SUCCESS;
     388                 :            : }
     389                 :            : 
     390                 :          0 : ErrorCode ReadMCNP5::set_header_tags( EntityHandle output_meshset, char date_and_time[100], char title[100],
     391                 :            :                                       unsigned long int nps, Tag data_and_time_tag, Tag title_tag, Tag nps_tag )
     392                 :            : {
     393                 :            :     ErrorCode result;
     394                 :          0 :     result = MBI->tag_set_data( data_and_time_tag, &output_meshset, 1, &date_and_time );
     395         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     396                 :          0 :     result = MBI->tag_set_data( title_tag, &output_meshset, 1, &title );
     397         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     398                 :          0 :     result = MBI->tag_set_data( nps_tag, &output_meshset, 1, &nps );
     399         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     400                 :            : 
     401                 :          0 :     return MB_SUCCESS;
     402                 :            : }
     403                 :            : 
     404                 :          0 : ErrorCode ReadMCNP5::read_tally_header( std::fstream& file, bool debug, unsigned int& tally_number,
     405                 :            :                                         char tally_comment[100], particle& tally_particle )
     406                 :            : {
     407                 :            :     // Get tally number
     408                 :            :     // Mesh Tally Number 104
     409                 :            :     ErrorCode result;
     410                 :            :     char line[100];
     411         [ #  # ]:          0 :     file.getline( line, 100 );
     412         [ #  # ]:          0 :     std::string a            = line;
     413         [ #  # ]:          0 :     std::string::size_type b = a.find( "Mesh Tally Number" );
     414         [ #  # ]:          0 :     if( std::string::npos != b )
     415                 :            :     {
     416 [ #  # ][ #  # ]:          0 :         std::istringstream tally_number_ss( a.substr( b + sizeof( "Mesh Tally Number" ), 100 ) );
     417         [ #  # ]:          0 :         tally_number_ss >> tally_number;
     418 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "tally_number=| " << tally_number << std::endl;
         [ #  # ][ #  # ]
     419                 :            :     }
     420                 :            :     else
     421                 :            :     {
     422 [ #  # ][ #  # ]:          0 :         std::cout << "tally number not found" << std::endl;
     423                 :          0 :         return MB_FAILURE;
     424                 :            :     }
     425                 :            : 
     426                 :            :     // Next get the tally comment (optional) and particle type
     427                 :            :     // 3mm neutron heating in Be (W/cc)
     428                 :            :     // This is a neutron mesh tally.
     429                 :            :     // std::string tally_comment;
     430                 :            : 
     431                 :            :     // Get tally particle
     432         [ #  # ]:          0 :     file.getline( line, 100 );
     433         [ #  # ]:          0 :     a      = line;
     434 [ #  # ][ #  # ]:          0 :     result = get_tally_particle( a, debug, tally_particle );
     435         [ #  # ]:          0 :     if( MB_FAILURE == result )
     436                 :            :     {
     437                 :            :         // If this line does not specify the particle type, then it is a tally comment.
     438                 :            :         // Get the comment, then get the particle type from the next line.
     439                 :          0 :         tally_comment = line;
     440         [ #  # ]:          0 :         file.getline( line, 100 );
     441         [ #  # ]:          0 :         a      = line;
     442 [ #  # ][ #  # ]:          0 :         result = get_tally_particle( a, debug, tally_particle );
     443         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     444                 :            :     }
     445 [ #  # ][ #  # ]:          0 :     if( debug ) std::cout << "tally_comment=| " << tally_comment << std::endl;
         [ #  # ][ #  # ]
     446                 :            : 
     447                 :          0 :     return MB_SUCCESS;
     448                 :            : }
     449                 :            : 
     450                 :          0 : ErrorCode ReadMCNP5::get_tally_particle( std::string a, bool debug, particle& tally_particle )
     451                 :            : {
     452         [ #  # ]:          0 :     if( std::string::npos != a.find( "This is a neutron mesh tally." ) ) { tally_particle = NEUTRON; }
     453         [ #  # ]:          0 :     else if( std::string::npos != a.find( "This is a photon mesh tally." ) )
     454                 :            :     {
     455                 :          0 :         tally_particle = PHOTON;
     456                 :            :     }
     457         [ #  # ]:          0 :     else if( std::string::npos != a.find( "This is an electron mesh tally." ) )
     458                 :            :     {
     459                 :          0 :         tally_particle = ELECTRON;
     460                 :            :     }
     461                 :            :     else
     462                 :          0 :         return MB_FAILURE;
     463                 :            : 
     464         [ #  # ]:          0 :     if( debug ) std::cout << "tally_particle=| " << tally_particle << std::endl;
     465                 :            : 
     466                 :          0 :     return MB_SUCCESS;
     467                 :            : }
     468                 :            : 
     469                 :          0 : ErrorCode ReadMCNP5::read_mesh_planes( std::fstream& file, bool debug, std::vector< double > planes[3],
     470                 :            :                                        coordinate_system& coord_sys )
     471                 :            : {
     472                 :            :     // Tally bin boundaries:
     473                 :            :     ErrorCode result;
     474                 :            :     char line[10000];
     475         [ #  # ]:          0 :     file.getline( line, 10000 );
     476         [ #  # ]:          0 :     std::string a = line;
     477 [ #  # ][ #  # ]:          0 :     if( std::string::npos == a.find( "Tally bin boundaries:" ) ) return MB_FAILURE;
     478                 :            : 
     479                 :            :     // Decide what coordinate system the tally is using
     480                 :            :     // first check for Cylindrical coordinates:
     481         [ #  # ]:          0 :     file.getline( line, 10000 );
     482         [ #  # ]:          0 :     a                        = line;
     483         [ #  # ]:          0 :     std::string::size_type b = a.find( "Cylinder origin at" );
     484         [ #  # ]:          0 :     if( std::string::npos != b )
     485                 :            :     {
     486                 :          0 :         coord_sys = CYLINDRICAL;
     487 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "origin, axis, direction=| " << a << std::endl;
         [ #  # ][ #  # ]
     488 [ #  # ][ #  # ]:          0 :         std::istringstream ss( a.substr( b + sizeof( "Cylinder origin at" ), 10000 ) );
     489                 :            :         // The meshtal file does not contain sufficient information to transform
     490                 :            :         // the particle. Although origin, axs, and vec is needed only origin and
     491                 :            :         // axs appear in the meshtal file. Why was vec omitted?.
     492                 :            :         // get origin (not used)
     493                 :            :         // Cylinder origin at   0.00E+00  0.00E+00  0.00E+00,
     494                 :            :         // axis in  0.000E+00 0.000E+00 1.000E+00 direction
     495                 :            :         double origin[3];
     496 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "origin=| ";
     497         [ #  # ]:          0 :         for( int i = 0; i < 3; i++ )
     498                 :            :         {
     499         [ #  # ]:          0 :             ss >> origin[i];
     500 [ #  # ][ #  # ]:          0 :             if( debug ) std::cout << origin[i] << " ";
                 [ #  # ]
     501                 :            :         }
     502 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << std::endl;
     503                 :          0 :         int length_of_string = 10;
     504         [ #  # ]:          0 :         ss.ignore( length_of_string, ' ' );
     505         [ #  # ]:          0 :         ss.ignore( length_of_string, ' ' );
     506         [ #  # ]:          0 :         ss.ignore( length_of_string, ' ' );
     507                 :            :         // Get axis (not used)
     508                 :            :         double axis[3];
     509 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "axis=| ";
     510         [ #  # ]:          0 :         for( int i = 0; i < 3; i++ )
     511                 :            :         {
     512         [ #  # ]:          0 :             ss >> axis[i];
     513 [ #  # ][ #  # ]:          0 :             if( debug ) std::cout << axis[i] << " ";
                 [ #  # ]
     514                 :            :         }
     515 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << std::endl;
     516         [ #  # ]:          0 :         file.getline( line, 10000 );
     517         [ #  # ]:          0 :         a = line;
     518                 :            : 
     519                 :            :         // Get r planes
     520 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "R direction:=| ";
     521         [ #  # ]:          0 :         b = a.find( "R direction:" );
     522         [ #  # ]:          0 :         if( std::string::npos != b )
     523                 :            :         {
     524 [ #  # ][ #  # ]:          0 :             std::istringstream ss2( a.substr( b + sizeof( "R direction" ), 10000 ) );
     525         [ #  # ]:          0 :             result = get_mesh_plane( ss2, debug, planes[0] );
     526 [ #  # ][ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     527                 :            :         }
     528                 :            :         else
     529                 :          0 :             return MB_FAILURE;
     530                 :            : 
     531                 :            :         // Get z planes
     532         [ #  # ]:          0 :         file.getline( line, 10000 );
     533         [ #  # ]:          0 :         a = line;
     534 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "Z direction:=| ";
     535         [ #  # ]:          0 :         b = a.find( "Z direction:" );
     536         [ #  # ]:          0 :         if( std::string::npos != b )
     537                 :            :         {
     538 [ #  # ][ #  # ]:          0 :             std::istringstream ss2( a.substr( b + sizeof( "Z direction" ), 10000 ) );
     539         [ #  # ]:          0 :             result = get_mesh_plane( ss2, debug, planes[1] );
     540 [ #  # ][ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     541                 :            :         }
     542                 :            :         else
     543                 :          0 :             return MB_FAILURE;
     544                 :            : 
     545                 :            :         // Get theta planes
     546         [ #  # ]:          0 :         file.getline( line, 10000 );
     547         [ #  # ]:          0 :         a = line;
     548 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "Theta direction:=| ";
     549         [ #  # ]:          0 :         b = a.find( "Theta direction (revolutions):" );
     550         [ #  # ]:          0 :         if( std::string::npos != b )
     551                 :            :         {
     552 [ #  # ][ #  # ]:          0 :             std::istringstream ss2( a.substr( b + sizeof( "Theta direction (revolutions):" ), 10000 ) );
     553         [ #  # ]:          0 :             result = get_mesh_plane( ss2, debug, planes[2] );
     554 [ #  # ][ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     555                 :            :         }
     556                 :            :         else
     557         [ #  # ]:          0 :             return MB_FAILURE;
     558                 :            : 
     559                 :            :         // Cartesian coordinate system:
     560                 :            :     }
     561 [ #  # ][ #  # ]:          0 :     else if( std::string::npos != a.find( "X direction:" ) )
     562                 :            :     {
     563                 :          0 :         coord_sys = CARTESIAN;
     564                 :            :         // Get x planes
     565 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "X direction:=| ";
     566         [ #  # ]:          0 :         b = a.find( "X direction:" );
     567         [ #  # ]:          0 :         if( std::string::npos != b )
     568                 :            :         {
     569 [ #  # ][ #  # ]:          0 :             std::istringstream ss2( a.substr( b + sizeof( "X direction" ), 10000 ) );
     570         [ #  # ]:          0 :             result = get_mesh_plane( ss2, debug, planes[0] );
     571 [ #  # ][ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     572                 :            :         }
     573                 :            :         else
     574                 :          0 :             return MB_FAILURE;
     575                 :            : 
     576                 :            :         // Get y planes
     577         [ #  # ]:          0 :         file.getline( line, 10000 );
     578         [ #  # ]:          0 :         a = line;
     579 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "Y direction:=| ";
     580         [ #  # ]:          0 :         b = a.find( "Y direction:" );
     581         [ #  # ]:          0 :         if( std::string::npos != b )
     582                 :            :         {
     583 [ #  # ][ #  # ]:          0 :             std::istringstream ss2( a.substr( b + sizeof( "Y direction" ), 10000 ) );
     584         [ #  # ]:          0 :             result = get_mesh_plane( ss2, debug, planes[1] );
     585 [ #  # ][ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     586                 :            :         }
     587                 :            :         else
     588                 :          0 :             return MB_FAILURE;
     589                 :            : 
     590                 :            :         // Get z planes
     591         [ #  # ]:          0 :         file.getline( line, 10000 );
     592         [ #  # ]:          0 :         a = line;
     593 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << "Z direction:=| ";
     594         [ #  # ]:          0 :         b = a.find( "Z direction:" );
     595         [ #  # ]:          0 :         if( std::string::npos != b )
     596                 :            :         {
     597 [ #  # ][ #  # ]:          0 :             std::istringstream ss2( a.substr( b + sizeof( "Z direction" ), 10000 ) );
     598         [ #  # ]:          0 :             result = get_mesh_plane( ss2, debug, planes[2] );
     599 [ #  # ][ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     600                 :            :         }
     601                 :            :         else
     602                 :          0 :             return MB_FAILURE;
     603                 :            : 
     604                 :            :         // Spherical coordinate system not yet implemented:
     605                 :            :     }
     606                 :            :     else
     607                 :          0 :         return MB_FAILURE;
     608                 :            : 
     609                 :          0 :     return MB_SUCCESS;
     610                 :            : }
     611                 :            : 
     612                 :            : // Given a stringstream, return a vector of values in the string.
     613                 :          0 : ErrorCode ReadMCNP5::get_mesh_plane( std::istringstream& ss, bool debug, std::vector< double >& plane )
     614                 :            : {
     615                 :            :     double value;
     616                 :          0 :     plane.clear();
     617 [ #  # ][ #  # ]:          0 :     while( !ss.eof() )
     618                 :            :     {
     619         [ #  # ]:          0 :         ss >> value;
     620         [ #  # ]:          0 :         plane.push_back( value );
     621 [ #  # ][ #  # ]:          0 :         if( debug ) std::cout << value << " ";
                 [ #  # ]
     622                 :            :     }
     623 [ #  # ][ #  # ]:          0 :     if( debug ) std::cout << std::endl;
     624                 :            : 
     625                 :          0 :     return MB_SUCCESS;
     626                 :            : }
     627                 :            : 
     628                 :          0 : ErrorCode ReadMCNP5::read_element_values_and_errors( std::fstream& file, bool /* debug */,
     629                 :            :                                                      std::vector< double > planes[3], unsigned int n_chopped_x0_planes,
     630                 :            :                                                      unsigned int n_chopped_x2_planes, particle tally_particle,
     631                 :            :                                                      double values[], double errors[] )
     632                 :            : {
     633                 :          0 :     unsigned int index = 0;
     634                 :            :     // Need to read every line in the file, even if we chop off some elements
     635         [ #  # ]:          0 :     for( unsigned int i = 0; i < planes[0].size() - 1 + n_chopped_x0_planes; i++ )
     636                 :            :     {
     637         [ #  # ]:          0 :         for( unsigned int j = 0; j < planes[1].size() - 1; j++ )
     638                 :            :         {
     639         [ #  # ]:          0 :             for( unsigned int k = 0; k < planes[2].size() - 1 + n_chopped_x2_planes; k++ )
     640                 :            :             {
     641                 :            :                 char line[100];
     642         [ #  # ]:          0 :                 file.getline( line, 100 );
     643                 :            :                 // If this element has been chopped off, skip it
     644         [ #  # ]:          0 :                 if( i < n_chopped_x0_planes ) continue;
     645 [ #  # ][ #  # ]:          0 :                 if( k >= planes[2].size() - 1 && k < planes[2].size() - 1 + n_chopped_x2_planes ) continue;
                 [ #  # ]
     646         [ #  # ]:          0 :                 std::string a = line;
     647 [ #  # ][ #  # ]:          0 :                 std::stringstream ss( a );
     648                 :            :                 double centroid[3];
     649                 :            :                 double energy;
     650                 :            :                 // For some reason, photon tallies print the energy in the first column
     651 [ #  # ][ #  # ]:          0 :                 if( PHOTON == tally_particle ) ss >> energy;
     652                 :            :                 // The centroid is not used in this reader
     653         [ #  # ]:          0 :                 ss >> centroid[0];
     654         [ #  # ]:          0 :                 ss >> centroid[1];
     655         [ #  # ]:          0 :                 ss >> centroid[2];
     656                 :            :                 // Only the tally values and errors are used
     657         [ #  # ]:          0 :                 ss >> values[index];
     658         [ #  # ]:          0 :                 ss >> errors[index];
     659                 :            : 
     660                 :            :                 // Make sure that input data is good
     661 [ #  # ][ #  # ]:          0 :                 if( !Util::is_finite( errors[index] ) )
     662                 :            :                 {
     663 [ #  # ][ #  # ]:          0 :                     std::cerr << "found nan error while reading file" << std::endl;
     664                 :          0 :                     errors[index] = 1.0;
     665                 :            :                 }
     666 [ #  # ][ #  # ]:          0 :                 if( !Util::is_finite( values[index] ) )
     667                 :            :                 {
     668 [ #  # ][ #  # ]:          0 :                     std::cerr << "found nan value while reading file" << std::endl;
     669                 :          0 :                     values[index] = 0.0;
     670                 :            :                 }
     671                 :            : 
     672                 :          0 :                 index++;
     673                 :          0 :             }
     674                 :            :         }
     675                 :            :     }
     676                 :            : 
     677                 :          0 :     return MB_SUCCESS;
     678                 :            : }
     679                 :            : 
     680                 :          0 : ErrorCode ReadMCNP5::set_tally_tags( EntityHandle tally_meshset, unsigned int tally_number, char tally_comment[100],
     681                 :            :                                      particle tally_particle, coordinate_system tally_coord_sys, Tag tally_number_tag,
     682                 :            :                                      Tag tally_comment_tag, Tag tally_particle_tag, Tag tally_coord_sys_tag )
     683                 :            : {
     684                 :            :     ErrorCode result;
     685                 :          0 :     result = MBI->tag_set_data( tally_number_tag, &tally_meshset, 1, &tally_number );
     686         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     687                 :          0 :     result = MBI->tag_set_data( tally_comment_tag, &tally_meshset, 1, &tally_comment );
     688         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     689                 :          0 :     result = MBI->tag_set_data( tally_particle_tag, &tally_meshset, 1, &tally_particle );
     690         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     691                 :          0 :     result = MBI->tag_set_data( tally_coord_sys_tag, &tally_meshset, 1, &tally_coord_sys );
     692         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     693                 :            : 
     694                 :          0 :     return MB_SUCCESS;
     695                 :            : }
     696                 :            : 
     697                 :          0 : ErrorCode ReadMCNP5::create_vertices( std::vector< double > planes[3], bool debug, EntityHandle& start_vert,
     698                 :            :                                       coordinate_system coord_sys, EntityHandle tally_meshset )
     699                 :            : {
     700                 :            :     // The only info needed to build elements is the mesh plane boundaries.
     701                 :            :     ErrorCode result;
     702                 :          0 :     int n_verts = planes[0].size() * planes[1].size() * planes[2].size();
     703 [ #  # ][ #  # ]:          0 :     if( debug ) std::cout << "n_verts=" << n_verts << std::endl;
         [ #  # ][ #  # ]
     704         [ #  # ]:          0 :     std::vector< double* > coord_arrays( 3 );
     705         [ #  # ]:          0 :     result = readMeshIface->get_node_coords( 3, n_verts, MB_START_ID, start_vert, coord_arrays );
     706         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     707         [ #  # ]:          0 :     assert( 0 != start_vert );  // Check for NULL
     708                 :            : 
     709         [ #  # ]:          0 :     for( unsigned int k = 0; k < planes[2].size(); k++ )
     710                 :            :     {
     711         [ #  # ]:          0 :         for( unsigned int j = 0; j < planes[1].size(); j++ )
     712                 :            :         {
     713         [ #  # ]:          0 :             for( unsigned int i = 0; i < planes[0].size(); i++ )
     714                 :            :             {
     715                 :          0 :                 unsigned int idx = ( k * planes[0].size() * planes[1].size() + j * planes[0].size() + i );
     716                 :            :                 double in[3], out[3];
     717                 :            : 
     718         [ #  # ]:          0 :                 in[0]  = planes[0][i];
     719         [ #  # ]:          0 :                 in[1]  = planes[1][j];
     720         [ #  # ]:          0 :                 in[2]  = planes[2][k];
     721         [ #  # ]:          0 :                 result = transform_point_to_cartesian( in, out, coord_sys );
     722         [ #  # ]:          0 :                 if( MB_SUCCESS != result ) return result;
     723                 :            : 
     724                 :            :                 // Cppcheck warning (false positive): variable coord_arrays is assigned a value that
     725                 :            :                 // is never used
     726         [ #  # ]:          0 :                 coord_arrays[0][idx] = out[0];
     727         [ #  # ]:          0 :                 coord_arrays[1][idx] = out[1];
     728         [ #  # ]:          0 :                 coord_arrays[2][idx] = out[2];
     729                 :            :             }
     730                 :            :         }
     731                 :            :     }
     732         [ #  # ]:          0 :     Range vert_range( start_vert, start_vert + n_verts - 1 );
     733         [ #  # ]:          0 :     result = MBI->add_entities( tally_meshset, vert_range );
     734         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     735                 :            : 
     736         [ #  # ]:          0 :     if( fileIDTag )
     737                 :            :     {
     738         [ #  # ]:          0 :         result = readMeshIface->assign_ids( *fileIDTag, vert_range, nodeId );
     739         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     740         [ #  # ]:          0 :         nodeId += vert_range.size();
     741                 :            :     }
     742                 :            : 
     743                 :          0 :     return MB_SUCCESS;
     744                 :            : }
     745                 :            : 
     746                 :          0 : ErrorCode ReadMCNP5::create_elements( bool debug, std::vector< double > planes[3], unsigned int /*n_chopped_x0_planes*/,
     747                 :            :                                       unsigned int /*n_chopped_x2_planes*/, EntityHandle start_vert, double* values,
     748                 :            :                                       double* errors, Tag tally_tag, Tag error_tag, EntityHandle tally_meshset,
     749                 :            :                                       coordinate_system tally_coord_sys )
     750                 :            : {
     751                 :            :     ErrorCode result;
     752                 :            :     unsigned int index;
     753                 :          0 :     EntityHandle start_element = 0;
     754                 :          0 :     unsigned int n_elements    = ( planes[0].size() - 1 ) * ( planes[1].size() - 1 ) * ( planes[2].size() - 1 );
     755                 :            :     EntityHandle* connect;
     756         [ #  # ]:          0 :     result = readMeshIface->get_element_connect( n_elements, 8, MBHEX, MB_START_ID, start_element, connect );
     757         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     758         [ #  # ]:          0 :     assert( 0 != start_element );  // Check for NULL
     759                 :            : 
     760                 :          0 :     unsigned int counter = 0;
     761         [ #  # ]:          0 :     for( unsigned int i = 0; i < planes[0].size() - 1; i++ )
     762                 :            :     {
     763         [ #  # ]:          0 :         for( unsigned int j = 0; j < planes[1].size() - 1; j++ )
     764                 :            :         {
     765         [ #  # ]:          0 :             for( unsigned int k = 0; k < planes[2].size() - 1; k++ )
     766                 :            :             {
     767                 :          0 :                 index = start_vert + i + j * planes[0].size() + k * planes[0].size() * planes[1].size();
     768                 :            :                 // For rectangular mesh, the file prints: x y z
     769                 :            :                 // z changes the fastest and x changes the slowest.
     770                 :            :                 // This means that the connectivity ordering is not consistent between
     771                 :            :                 // rectangular and cylindrical mesh.
     772         [ #  # ]:          0 :                 if( CARTESIAN == tally_coord_sys )
     773                 :            :                 {
     774                 :          0 :                     connect[0] = index;
     775                 :          0 :                     connect[1] = index + 1;
     776                 :          0 :                     connect[2] = index + 1 + planes[0].size();
     777                 :          0 :                     connect[3] = index + planes[0].size();
     778                 :          0 :                     connect[4] = index + planes[0].size() * planes[1].size();
     779                 :          0 :                     connect[5] = index + 1 + planes[0].size() * planes[1].size();
     780                 :          0 :                     connect[6] = index + 1 + planes[0].size() + planes[0].size() * planes[1].size();
     781                 :          0 :                     connect[7] = index + planes[0].size() + planes[0].size() * planes[1].size();
     782                 :            :                     // For cylindrical mesh, the file prints: r z theta
     783                 :            :                     // Theta changes the fastest and r changes the slowest.
     784                 :            :                 }
     785         [ #  # ]:          0 :                 else if( CYLINDRICAL == tally_coord_sys )
     786                 :            :                 {
     787                 :          0 :                     connect[0] = index;
     788                 :          0 :                     connect[1] = index + 1;
     789                 :          0 :                     connect[2] = index + 1 + planes[0].size() * planes[1].size();
     790                 :          0 :                     connect[3] = index + planes[0].size() * planes[1].size();
     791                 :          0 :                     connect[4] = index + planes[0].size();
     792                 :          0 :                     connect[5] = index + 1 + planes[0].size();
     793                 :          0 :                     connect[6] = index + 1 + planes[0].size() + planes[0].size() * planes[1].size();
     794                 :          0 :                     connect[7] = index + planes[0].size() + planes[0].size() * planes[1].size();
     795                 :            :                 }
     796                 :            :                 else
     797                 :          0 :                     return MB_NOT_IMPLEMENTED;
     798                 :            : 
     799                 :          0 :                 connect += 8;
     800                 :          0 :                 counter++;
     801                 :            :             }
     802                 :            :         }
     803                 :            :     }
     804 [ #  # ][ #  # ]:          0 :     if( counter != n_elements ) std::cout << "counter=" << counter << " n_elements=" << n_elements << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     805                 :            : 
     806         [ #  # ]:          0 :     Range element_range( start_element, start_element + n_elements - 1 );
     807         [ #  # ]:          0 :     result = MBI->tag_set_data( tally_tag, element_range, values );
     808         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     809         [ #  # ]:          0 :     result = MBI->tag_set_data( error_tag, element_range, errors );
     810         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     811                 :            : 
     812                 :            :     // Add the elements to the tally set
     813         [ #  # ]:          0 :     result = MBI->add_entities( tally_meshset, element_range );
     814         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     815 [ #  # ][ #  # ]:          0 :     if( debug ) std::cout << "Read " << n_elements << " elements from tally." << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
     816                 :            : 
     817         [ #  # ]:          0 :     if( fileIDTag )
     818                 :            :     {
     819         [ #  # ]:          0 :         result = readMeshIface->assign_ids( *fileIDTag, element_range, elemId );
     820         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     821         [ #  # ]:          0 :         elemId += element_range.size();
     822                 :            :     }
     823                 :            : 
     824                 :          0 :     return MB_SUCCESS;
     825                 :            : }
     826                 :            : 
     827                 :            : // Average a tally that was recently read in with one that already exists in
     828                 :            : // the interface. Only the existing values will be updated.
     829                 :          0 : ErrorCode ReadMCNP5::average_with_existing_tally( bool debug, unsigned long int& new_nps, unsigned long int nps1,
     830                 :            :                                                   unsigned int tally_number, Tag tally_number_tag, Tag nps_tag,
     831                 :            :                                                   Tag tally_tag, Tag error_tag, double* values1, double* errors1,
     832                 :            :                                                   unsigned int n_elements )
     833                 :            : {
     834                 :            :     // Get the tally number
     835                 :            :     ErrorCode result;
     836                 :            : 
     837                 :            :     // Match the tally number with one from the existing meshtal file
     838         [ #  # ]:          0 :     Range matching_tally_number_sets;
     839                 :          0 :     const void* const tally_number_val[] = { &tally_number };
     840                 :            :     result = MBI->get_entities_by_type_and_tag( 0, MBENTITYSET, &tally_number_tag, tally_number_val, 1,
     841         [ #  # ]:          0 :                                                 matching_tally_number_sets );
     842         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     843 [ #  # ][ #  # ]:          0 :     if( debug ) std::cout << "number of matching meshsets=" << matching_tally_number_sets.size() << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
     844 [ #  # ][ #  # ]:          0 :     assert( 1 == matching_tally_number_sets.size() );
     845                 :            : 
     846                 :            :     // Identify which of the meshsets is existing
     847                 :            :     EntityHandle existing_meshset;
     848         [ #  # ]:          0 :     existing_meshset = matching_tally_number_sets.front();
     849                 :            : 
     850                 :            :     // Get the existing elements from the set
     851         [ #  # ]:          0 :     Range existing_elements;
     852         [ #  # ]:          0 :     result = MBI->get_entities_by_type( existing_meshset, MBHEX, existing_elements );
     853         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     854 [ #  # ][ #  # ]:          0 :     assert( existing_elements.size() == n_elements );
     855                 :            : 
     856                 :            :     // Get the nps of the existing and new tally
     857                 :            :     unsigned long int nps0;
     858         [ #  # ]:          0 :     Range sets_with_this_tag;
     859         [ #  # ]:          0 :     result = MBI->get_entities_by_type_and_tag( 0, MBENTITYSET, &nps_tag, 0, 1, sets_with_this_tag );
     860         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     861 [ #  # ][ #  # ]:          0 :     if( debug ) std::cout << "number of nps sets=" << sets_with_this_tag.size() << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
     862 [ #  # ][ #  # ]:          0 :     assert( 1 == sets_with_this_tag.size() );
     863 [ #  # ][ #  # ]:          0 :     result = MBI->tag_get_data( nps_tag, &sets_with_this_tag.front(), 1, &nps0 );
     864         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     865 [ #  # ][ #  # ]:          0 :     if( debug ) std::cout << "nps0=" << nps0 << " nps1=" << nps1 << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     866                 :          0 :     new_nps = nps0 + nps1;
     867                 :            : 
     868                 :            :     // Get tally values from the existing elements
     869 [ #  # ][ #  # ]:          0 :     double* values0 = new double[existing_elements.size()];
                 [ #  # ]
     870 [ #  # ][ #  # ]:          0 :     double* errors0 = new double[existing_elements.size()];
                 [ #  # ]
     871         [ #  # ]:          0 :     result          = MBI->tag_get_data( tally_tag, existing_elements, values0 );
     872         [ #  # ]:          0 :     if( MB_SUCCESS != result )
     873                 :            :     {
     874         [ #  # ]:          0 :         delete[] values0;
     875         [ #  # ]:          0 :         delete[] errors0;
     876                 :          0 :         return result;
     877                 :            :     }
     878         [ #  # ]:          0 :     result = MBI->tag_get_data( error_tag, existing_elements, errors0 );
     879         [ #  # ]:          0 :     if( MB_SUCCESS != result )
     880                 :            :     {
     881         [ #  # ]:          0 :         delete[] values0;
     882         [ #  # ]:          0 :         delete[] errors0;
     883                 :          0 :         return result;
     884                 :            :     }
     885                 :            : 
     886                 :            :     // Average the values and errors
     887         [ #  # ]:          0 :     result = average_tally_values( nps0, nps1, values0, values1, errors0, errors1, n_elements );
     888         [ #  # ]:          0 :     if( MB_SUCCESS != result )
     889                 :            :     {
     890         [ #  # ]:          0 :         delete[] values0;
     891         [ #  # ]:          0 :         delete[] errors0;
     892                 :          0 :         return result;
     893                 :            :     }
     894                 :            : 
     895                 :            :     // Set the averaged information back onto the existing elements
     896         [ #  # ]:          0 :     result = MBI->tag_set_data( tally_tag, existing_elements, values0 );
     897         [ #  # ]:          0 :     if( MB_SUCCESS != result )
     898                 :            :     {
     899         [ #  # ]:          0 :         delete[] values0;
     900         [ #  # ]:          0 :         delete[] errors0;
     901                 :          0 :         return result;
     902                 :            :     }
     903         [ #  # ]:          0 :     result = MBI->tag_set_data( error_tag, existing_elements, errors0 );
     904         [ #  # ]:          0 :     if( MB_SUCCESS != result )
     905                 :            :     {
     906         [ #  # ]:          0 :         delete[] values0;
     907         [ #  # ]:          0 :         delete[] errors0;
     908                 :          0 :         return result;
     909                 :            :     }
     910                 :            : 
     911                 :            :     // Cleanup
     912         [ #  # ]:          0 :     delete[] values0;
     913         [ #  # ]:          0 :     delete[] errors0;
     914                 :            : 
     915                 :          0 :     return MB_SUCCESS;
     916                 :            : }
     917                 :            : 
     918                 :          0 : ErrorCode ReadMCNP5::transform_point_to_cartesian( double* in, double* out, coordinate_system coord_sys )
     919                 :            : {
     920                 :            :     // Transform coordinate system
     921   [ #  #  #  # ]:          0 :     switch( coord_sys )
     922                 :            :     {
     923                 :            :         case CARTESIAN:
     924                 :          0 :             out[0] = in[0];  // x
     925                 :          0 :             out[1] = in[1];  // y
     926                 :          0 :             out[2] = in[2];  // z
     927                 :          0 :             break;
     928                 :            :         // theta is in rotations
     929                 :            :         case CYLINDRICAL:
     930                 :          0 :             out[0] = in[0] * cos( 2 * PI * in[2] );  // x
     931                 :          0 :             out[1] = in[0] * sin( 2 * PI * in[2] );  // y
     932                 :          0 :             out[2] = in[1];                          // z
     933                 :          0 :             break;
     934                 :            :         case SPHERICAL:
     935                 :          0 :             return MB_NOT_IMPLEMENTED;
     936                 :            :         default:
     937                 :          0 :             return MB_NOT_IMPLEMENTED;
     938                 :            :     }
     939                 :            : 
     940                 :          0 :     return MB_SUCCESS;
     941                 :            : }
     942                 :            : 
     943                 :            : // Average two tally values and their error. Return average values in the
     944                 :            : // place of first tally values.
     945                 :          0 : ErrorCode ReadMCNP5::average_tally_values( const unsigned long int nps0, const unsigned long int nps1, double* values0,
     946                 :            :                                            const double* values1, double* errors0, const double* errors1,
     947                 :            :                                            const unsigned long int n_values )
     948                 :            : {
     949         [ #  # ]:          0 :     for( unsigned long int i = 0; i < n_values; i++ )
     950                 :            :     {
     951                 :            :         // std::cout << " values0=" << values0[i] << " values1=" << values1[i]
     952                 :            :         //          << " errors0=" << errors0[i] << " errors1=" << errors1[i]
     953                 :            :         //          << " nps0=" << nps0 << " nps1=" << nps1 << std::endl;
     954                 :          0 :         errors0[i] = sqrt( pow( values0[i] * errors0[i] * nps0, 2 ) + pow( values1[i] * errors1[i] * nps1, 2 ) ) /
     955                 :          0 :                      ( values0[i] * nps0 + values1[i] * nps1 );
     956                 :            : 
     957                 :            :         // It is possible to introduce nans if the values are zero.
     958         [ #  # ]:          0 :         if( !Util::is_finite( errors0[i] ) ) errors0[i] = 1.0;
     959                 :            : 
     960                 :          0 :         values0[i] = ( values0[i] * nps0 + values1[i] * nps1 ) / ( nps0 + nps1 );
     961                 :            : 
     962                 :            :         // std::cout << " values0=" << values0[i] << " errors0=" << errors0[i] << std::endl;
     963                 :            :     }
     964                 :            :     // REMEMBER TO UPDATE NPS0 = NPS0 + NPS1 after this
     965                 :            : 
     966                 :          0 :     return MB_SUCCESS;
     967                 :            : }
     968                 :            : 
     969 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11