cgma
CellCardImpl Class Reference
Inheritance diagram for CellCardImpl:
CellCard Card

List of all members.

Public Member Functions

 CellCardImpl (InputDeck &deck, const token_list_t &tokens)
 ~CellCardImpl ()
virtual int getIdent () const
virtual const geom_list_t getGeom () const
virtual const DataRef
< Transform > & 
getTrcl () const
virtual int getUniverse () const
virtual bool hasFill () const
virtual const FillgetFill () const
virtual bool isLattice () const
virtual lattice_type_t getLatticeType () const
virtual const LatticegetLattice () const
virtual int getMat () const
virtual double getRho () const
virtual const std::map< char,
double > & 
getImportances () const
virtual void print (std::ostream &s) const

Protected Member Functions

void retokenize_geometry (const token_list_t &tokens)
void shunt_geometry ()
Vector3d latticeVectorHelper (Vector3d difference_along_normal, Vector3d v_dir)
void setupLattice ()
void makeData ()
void finish ()

Static Protected Member Functions

static geom_list_entry_t make_geom_entry (geom_token_t t, int param=0)
static bool is_num_token (geom_list_entry_t t)
static bool is_op_token (geom_list_entry_t t)
static int operator_priority (geom_list_entry_t t)

Protected Attributes

int ident
int material
double rho
std::map< char, double > importances
geom_list_t geom
token_list_t data
DataRef< Transform > * trcl
DataRef< Fill > * fill
int universe
bool likenbut
int likeness_cell_n
lattice_type_t lat_type
DataRef< Lattice > * lattice

Friends

class InputDeck

Detailed Description

Definition at line 228 of file MCNPInput.cpp.


Constructor & Destructor Documentation

CellCardImpl::CellCardImpl ( InputDeck deck,
const token_list_t tokens 
) [inline]

Definition at line 655 of file MCNPInput.cpp.

                                                              : 
    CellCard( deck ), trcl(NULL), fill(NULL), universe(0), likenbut(false), likeness_cell_n(0), 
    lat_type(NONE), lattice(NULL)
  {
    
    unsigned int idx = 0;

    ident = makeint(tokens.at(idx++));
    
    if(tokens.at(idx) == "like"){

      idx++;
      likenbut = true;
      likeness_cell_n = makeint(tokens.at(idx++));
      idx++; // skip the "but" token
      while(idx < tokens.size()){
        data.push_back(tokens[idx++]);
      }
      return;
    }

    material = makeint(tokens.at(idx++));
    rho = 0.0;
    if(material != 0){
      rho = makedouble(tokens.at(idx++)); // material density
    }

    token_list_t temp_geom;
    
    // while the tokens appear in geometry-specification syntax, store them into temporary list
    while(idx < tokens.size() && tokens.at(idx).find_first_of("1234567890:#-+()") == 0){
      temp_geom.push_back(tokens[idx++]);
    }

    // retokenize the geometry list, which follows a specialized syntax.
    retokenize_geometry( temp_geom );
    shunt_geometry();

    // store the rest of the tokens into the data list
    while(idx < tokens.size()){
      data.push_back(tokens[idx++]);
    }

    makeData();

  }

Definition at line 702 of file MCNPInput.cpp.

                 {
    if(trcl)
      delete trcl;
    if(fill)
      delete fill;
    if(lattice)
      delete lattice;
  }

Member Function Documentation

void CellCardImpl::finish ( ) [inline, protected]

Definition at line 749 of file MCNPInput.cpp.

               {
    if( likenbut ){
      CellCardImpl* host = dynamic_cast<CellCardImpl*>(parent_deck.lookup_cell_card( likeness_cell_n ));
      if(host->likenbut){
        host->finish(); // infinite recursion if cells are circularly defined... but our users wouldn't do that, right?
      }
      geom = host->geom;
      universe = host->universe;
      lat_type = host->lat_type;
      material = host->material;
      rho = host->rho;
      importances = host->importances;

      if( host->trcl->hasData()){
        trcl = host->trcl->clone();
      }
      if( host->hasFill()){
        fill = host->fill->clone();
      }
      if( host->isLattice()){
        lattice = host->lattice->clone();
      }
      makeData();

      likenbut = false;
    }

    if( lat_type != NONE && lattice == NULL ){
      setupLattice();
    }

  }
virtual const Fill& CellCardImpl::getFill ( ) const [inline, virtual]

Implements CellCard.

Definition at line 718 of file MCNPInput.cpp.

                                      { 
    if( fill && fill->hasData() ){
      return fill->getData();
    }
    throw std::runtime_error( "Called getFill() on an unfilled cell");
  }
virtual const geom_list_t CellCardImpl::getGeom ( ) const [inline, virtual]

Implements CellCard.

Definition at line 712 of file MCNPInput.cpp.

{ return geom; }
virtual int CellCardImpl::getIdent ( ) const [inline, virtual]

Implements CellCard.

Definition at line 711 of file MCNPInput.cpp.

{ return ident; }
virtual const std::map<char,double>& CellCardImpl::getImportances ( ) const [inline, virtual]

Implements CellCard.

Definition at line 742 of file MCNPInput.cpp.

{ return importances; }
virtual const Lattice& CellCardImpl::getLattice ( ) const [inline, virtual]

Implements CellCard.

Definition at line 733 of file MCNPInput.cpp.

                                            {
    if( lattice && lattice->hasData() ){
      return lattice->getData();
    }
    throw std::runtime_error( "Called getLattice() on a cell that hasn't got one" );
  }
virtual lattice_type_t CellCardImpl::getLatticeType ( ) const [inline, virtual]

Implements CellCard.

Definition at line 729 of file MCNPInput.cpp.

                                                {
    return lat_type;
  }
virtual int CellCardImpl::getMat ( ) const [inline, virtual]

Implements CellCard.

Definition at line 740 of file MCNPInput.cpp.

{ return material; }
virtual double CellCardImpl::getRho ( ) const [inline, virtual]

Implements CellCard.

Definition at line 741 of file MCNPInput.cpp.

{ return rho; }
virtual const DataRef<Transform>& CellCardImpl::getTrcl ( ) const [inline, virtual]

Implements CellCard.

Definition at line 714 of file MCNPInput.cpp.

{ return *trcl; }
virtual int CellCardImpl::getUniverse ( ) const [inline, virtual]

Implements CellCard.

Definition at line 715 of file MCNPInput.cpp.

{ return universe; }
virtual bool CellCardImpl::hasFill ( ) const [inline, virtual]

Implements CellCard.

Definition at line 717 of file MCNPInput.cpp.

{ return fill && fill->hasData(); }
static bool CellCardImpl::is_num_token ( geom_list_entry_t  t) [inline, static, protected]

Definition at line 235 of file MCNPInput.cpp.

                                                 {
    return t.first == CELLNUM || t.first == SURFNUM || t.first == MBODYFACET;
  }
static bool CellCardImpl::is_op_token ( geom_list_entry_t  t) [inline, static, protected]

Definition at line 239 of file MCNPInput.cpp.

                                                {
    return t.first == COMPLEMENT || t.first == UNION || t.first == INTERSECT;
  }
virtual bool CellCardImpl::isLattice ( ) const [inline, virtual]

Implements CellCard.

Definition at line 725 of file MCNPInput.cpp.

                                 {
    return lat_type != NONE;
  }
Vector3d CellCardImpl::latticeVectorHelper ( Vector3d  difference_along_normal,
Vector3d  v_dir 
) [inline, protected]

Definition at line 390 of file MCNPInput.cpp.

                                                                                  {
    double length = difference_along_normal.length() / (difference_along_normal.normalize().dot(v_dir));
    return v_dir * length;
  }
static geom_list_entry_t CellCardImpl::make_geom_entry ( geom_token_t  t,
int  param = 0 
) [inline, static, protected]

Definition at line 231 of file MCNPInput.cpp.

                                                                         {
    return std::make_pair(t, param);
  }
void CellCardImpl::makeData ( ) [inline, protected]

Definition at line 527 of file MCNPInput.cpp.

                 {

    for( token_list_t::iterator i = data.begin(); i!=data.end(); ++i ){

      std::string token = *i;

      if( token == "trcl" || token == "*trcl" ){
        bool degree_format = (token[0] == '*');

        i++;
        trcl = parseTransform( parent_deck, i, degree_format );

      } // token == {*}trcl

      else if( token == "u" ){
        universe = makeint(*(++i));
      } // token == "u"
      else if ( token == "lat" ){
        int lat_designator = makeint(*(++i));
        assert( lat_designator >= 0 && lat_designator <= 2 );
        lat_type = static_cast<lattice_type_t>(lat_designator);
        if( OPT_DEBUG ) std::cout << "cell " << ident << " is lattice type " << lat_type << std::endl;
      }
      else if ( token == "mat" ){
        material = makeint(*(++i));
      }
      else if ( token == "rho" ){
        rho = makedouble(*(++i));
      }
      else if ( token.length() == 5 && token.substr(0,4) == "imp:" ){
        double imp = makedouble(*(++i));
        importances[token[4]] = imp;
      }
      else if( token == "fill" || token == "*fill" ){

        bool degree_format = (token[0] == '*');

        std::string next_token = *(++i);

        // an explicit lattice grid exists if 
        // * the next token contains a colon, or
        // * the token after it exists and starts with a colon
        bool explicit_grid = next_token.find(":") != next_token.npos; 
        explicit_grid = explicit_grid || (i+1 != data.end() && (*(i+1)).at(0) == ':' );

        if( explicit_grid ){

          // convert the grid specifiers (x1:x2, y1:y2, z1:z2) into three spaceless strings for easier parsing
          std::string gridspec[3];
          for( int dim = 0; dim < 3; ++dim ){

            std::string spec;

            // add tokens to the spec string until it contains a colon but does not end with one
            do{
              spec += *i;
              i++;
            }
            while( spec.find(":") == spec.npos || spec.at(spec.length()-1) == ':' );
            
            if(OPT_DEBUG) std::cout << "gridspec[" << dim << "]: " << spec << std::endl;
            gridspec[dim] = spec;

          }

          irange ranges[3];
          const char* range_str;
          char *p;
          
          int num_elements = 1;
          for( int dim = 0; dim < 3; ++dim ){
            range_str = gridspec[dim].c_str();
            ranges[dim].first  = strtol(range_str, &p, 10);
            ranges[dim].second = strtol(p+1, NULL, 10); 
            
            if( ranges[dim].second != ranges[dim].first ){
              num_elements *= ( ranges[dim].second - ranges[dim].first )+1;
            }

          }

          std::vector<FillNode> elements;
          for( int j = 0; j < num_elements; ++j ){
            elements.push_back( parseFillNode( parent_deck, i, data.end(), degree_format )  );
            i++;
          }
          i--;

          fill = new ImmediateRef< Fill >( Fill( ranges[0], ranges[1], ranges[2], elements) );

        }
        else{ // no explicit grid; fill card is a single fill node
          FillNode filler = parseFillNode( parent_deck, i, data.end(), degree_format );
          fill = new ImmediateRef< Fill >( Fill(filler) );
          
        }
      } // token == {*}fill
    }

    // ensure data pointers are valid
    if( !trcl ) {
      trcl = new NullRef< Transform >();
    }

    if( !fill ){
      fill = new NullRef< Fill > ();
    }

  }
static int CellCardImpl::operator_priority ( geom_list_entry_t  t) [inline, static, protected]

Definition at line 243 of file MCNPInput.cpp.

                                                     {
    switch(t.first){
    case COMPLEMENT: return 3;
    case INTERSECT:  return 2;
    case UNION:      return 1;
    default:
      throw std::runtime_error("queried operator priority for a non-operator token");
    }
  }
virtual void CellCardImpl::print ( std::ostream &  s) const [inline, virtual]

Implements CellCard.

Definition at line 744 of file MCNPInput.cpp.

                                           {
    s << "Cell " << ident << " geom " << geom << std::endl;
  }
void CellCardImpl::retokenize_geometry ( const token_list_t tokens) [inline, protected]

Build the geom list as part of cell construction. Each item in the list will be a string; either " ", ":", or "#", indicating operators, or parentheses, or numbers indicating surface or cell identities.

Parameters:
Thelist of geometry tokens in the input file, as a list of strings that were separated by white space in the original file.

Definition at line 261 of file MCNPInput.cpp.

                                                        {
    for(token_list_t::const_iterator i = tokens.begin(); i!=tokens.end(); ++i){
      const std::string& token = *i;
      
      size_t j = 0;
      while( j < token.length() ){

        char cj = token.at(j);

        switch(cj){
          
          // the following macro pushes an intersect token onto the geom list
          // if the end of that list indicates that one is needed
#define IMPLICIT_INTERSECT() do{                                \
            if(geom.size()){                                    \
              geom_list_entry_t &t = geom.at(geom.size()-1);    \
              if( is_num_token(t) || t.first == RPAREN ){       \
                geom.push_back( make_geom_entry( INTERSECT ) ); \
              }}} while(0) 
          
        case '(': 
          IMPLICIT_INTERSECT();
          geom.push_back(make_geom_entry(LPAREN)); j++;
          break;
          
        case ')':
          geom.push_back(make_geom_entry(RPAREN)); j++;
          break;
          
        case '#':
          IMPLICIT_INTERSECT();
          geom.push_back(make_geom_entry(COMPLEMENT)); j++; 
          break;
          
        case ':':
          geom.push_back(make_geom_entry(UNION)); j++; 
          break;
          
        default: // a number
          // the number refers to a cell if the previous token is a complement
          bool is_cell = geom.size() && ((geom.at(geom.size()-1)).first == COMPLEMENT);
          IMPLICIT_INTERSECT();
          assert(isdigit(cj) || cj == '+' || cj == '-' );
          size_t end = token.find_first_not_of("1234567890-+.",j);
          assert(j != end);

          std::string numstr( token, j, end-j );
          const char* numstr_c = numstr.c_str();
          char* p;
          int num = strtol( numstr_c, &p, 10 );

          if( *p == '.' ){
            // This is a macrobody facet
            assert( !is_cell );

            int facet = strtol( p+1, NULL, 10 );
            assert( facet > 0 && facet <= 8 );

            // storage of macrobody facets: multiply cell number by ten, add facet number
            num *= 10;
            // don't add a positive facet number to a negative cell numer
            num += (num > 0) ? facet : -facet;
            geom.push_back( make_geom_entry( MBODYFACET, num ) );
          }
          else{
            geom.push_back( make_geom_entry( is_cell ? CELLNUM : SURFNUM, num ));
          }

          j += (end-j);
          break;
#undef IMPLICIT_INTERSECT

        }
        
      } 
    }
    
    if( OPT_DEBUG ) std::cout << tokens << " -> " << geom << std::endl;
    
  }
void CellCardImpl::setupLattice ( ) [inline, protected]

Definition at line 395 of file MCNPInput.cpp.

                     {

    if( OPT_DEBUG ) std::cout << "Setting up lattice for cell " << ident << std::endl;

    std::vector< std::pair<SurfaceCard*,bool> > surfaceCards;
    
    for( geom_list_t::iterator i = geom.begin(); i!=geom.end(); ++i){
      geom_list_entry_t entry = *i;
      if( entry.first == SURFNUM ){
        SurfaceCard* surf = parent_deck.lookup_surface_card( std::abs(entry.second) );
        assert(surf);
        surfaceCards.push_back( std::make_pair(surf, (entry.second>0) ) );
      }
    }

    int num_finite_dims = 0;
    Vector3d v1, v2, v3;

    std::vector< std::pair<Vector3d, double> > planes;

    if( surfaceCards.size() == 1 ){ 
      planes = surfaceCards.at(0).first->getMacrobodyPlaneParams();
      if( surfaceCards.at(0).second != false ){
        std::cerr << "Warning: macrobody lattice with positive sense, will proceed as if it was negative.";
      }
    }
    else{
      for( unsigned int i = 0; i < surfaceCards.size(); ++i){
        planes.push_back( surfaceCards.at(i).first->getPlaneParams() );
        if( surfaceCards.at(i).second == true ){ planes[i].first = -planes[i].first; }
      }
    }

    if( OPT_DEBUG ){
      for( unsigned int i = 0; i < planes.size(); ++i){
        std::cout << " plane " << i << " normal = " << planes[i].first << " d = " << planes[i].second  << std::endl;
      }
    }
    if( lat_type == HEXAHEDRAL ){
      assert( planes.size() == 2 || planes.size() == 4 || planes.size() == 6 );
      if( planes.size() == 2 ){

        num_finite_dims = 1;
        v1 = planes[0].first.normalize() * std::fabs( planes[0].second - planes[1].second ); 

      }
      else if( planes.size() == 4 ){
        num_finite_dims = 2;
        
        Vector3d v3 = planes[0].first.cross( planes[2].first ).normalize(); // infer a third (infinite) direction
        
        // vector from planes[1] to planes[0]
        Vector3d xv = planes[0].first.normalize() * std::fabs( planes[0].second - planes[1].second );

        // direction of l.v1: cross product of normals planes[2] and v3
        Vector3d xv2 = planes[2].first.normalize().cross( v3 ).normalize();
        v1 = latticeVectorHelper( xv, xv2 );

        Vector3d yv = planes[2].first.normalize() * std::fabs( planes[2].second - planes[3].second );
        Vector3d yv2 = planes[0].first.normalize().cross( v3 ).normalize();
        v2 = latticeVectorHelper( yv, yv2 );


      }
      else{ // planes.size() == 6 
        num_finite_dims = 3;

        // vector from planes[1] to planes[0]
        Vector3d xv = planes[0].first.normalize() * std::fabs( planes[0].second - planes[1].second );

        // direction of v1: cross product of normals planes[2] and planes[4]
        Vector3d xv2 = planes[2].first.normalize().cross( planes[4].first.normalize() ).normalize();
        v1 = latticeVectorHelper( xv, xv2 );

        Vector3d yv = planes[2].first.normalize() * std::fabs( planes[2].second - planes[3].second );
        Vector3d yv2 = planes[0].first.normalize().cross( planes[4].first.normalize() ).normalize();
        v2 = latticeVectorHelper( yv, yv2 );

        Vector3d zv = planes[4].first.normalize() * std::fabs( planes[4].second - planes[5].second );
        Vector3d zv2 = planes[0].first.normalize().cross( planes[2].first.normalize() ).normalize();
        v3 = latticeVectorHelper( zv, zv2 );
        
      }
      
    }
    else if( lat_type == HEXAGONAL ){
      assert( planes.size() == 6 || planes.size() == 8 );

      v3 = planes[0].first.cross( planes[2].first ).normalize(); // prism's primary axis

      // vector from planes[1] to planes[0]
      Vector3d xv = planes[0].first.normalize() * std::fabs( planes[0].second - planes[1].second );
      
      // direction of l.v1: cross product of normals average(planes[2]+planes[4]) and v3
      // TODO: this averaging trick only works with regular hexagons...
      Vector3d xv2 = (planes[2].first.normalize()+planes[4].first.normalize()).normalize().cross( v3 ).normalize();
      v1 = latticeVectorHelper( xv, xv2 );
      
      Vector3d yv = planes[2].first.normalize() * std::fabs( planes[2].second - planes[3].second );
      Vector3d yv2 = (planes[1].first.normalize()+planes[4].first.normalize()).normalize().cross( v3 ).normalize();
      v2 = latticeVectorHelper( yv, yv2 );
      

      if( planes.size() == 6 ){
        num_finite_dims = 2;
        
      }
      else{ // planes.size() == 8
        num_finite_dims = 3;

        Vector3d zv = planes[6].first.normalize() * std::fabs( planes[6].second - planes[7].second );
        Vector3d zv2 = v3;
        v3 = latticeVectorHelper( zv, zv2 );
      }
    }

    if( OPT_DEBUG )std::cout << " dims " << num_finite_dims << " vectors " << v1 << v2 << v3 << std::endl;
    
    Lattice l;
    if( fill->hasData() ){
      l = Lattice( num_finite_dims, v1, v2, v3, fill->getData() );
    }
    else{
      FillNode n( this->universe );
      l = Lattice( num_finite_dims, v1, v2, v3,  n );
    }

    lattice = new ImmediateRef<Lattice>( l );

    
  }
void CellCardImpl::shunt_geometry ( ) [inline, protected]

The final step of geometry parsing: convert the geometry list to RPN, which greatly simplifies the process of evaluating the geometry later. This function uses the shunting yard algorithm. For more info consult http://en.wikipedia.org/wiki/Shunting_yard_algorithm

Definition at line 349 of file MCNPInput.cpp.

                        {
    geom_list_t geom_copy( geom );
    geom.clear();

    geom_list_t stack;
    for(geom_list_t::iterator i = geom_copy.begin(); i!=geom_copy.end(); ++i){
      geom_list_entry_t token = *i;
      if( is_num_token(token) ){
        geom.push_back(token);
      }
      else if( is_op_token(token) ){

        while(stack.size()){
          geom_list_entry_t& stack_top = stack.back();
          if( is_op_token(stack_top) && operator_priority(stack_top) > operator_priority(token) ){
            geom.push_back(stack_top);
            stack.pop_back();
          }
          else{
            break;
          }
        }
        stack.push_back(token);
      }
      else if( token.first == LPAREN ){
        stack.push_back(token);
      }
      else if( token.first == RPAREN ){
        while( stack.back().first != LPAREN ){
          geom.push_back( stack.back() );
          stack.pop_back();
        }
        stack.pop_back(); // remove the LPAREN
      }
    }
    while( stack.size() ){
      geom.push_back( stack.back() );
      stack.pop_back();
    }
  }

Friends And Related Function Documentation

friend class InputDeck [friend]

Definition at line 782 of file MCNPInput.cpp.


Member Data Documentation

Definition at line 643 of file MCNPInput.cpp.

Definition at line 645 of file MCNPInput.cpp.

Definition at line 642 of file MCNPInput.cpp.

int CellCardImpl::ident [protected]

Definition at line 637 of file MCNPInput.cpp.

std::map<char, double> CellCardImpl::importances [protected]

Definition at line 640 of file MCNPInput.cpp.

Definition at line 651 of file MCNPInput.cpp.

Definition at line 652 of file MCNPInput.cpp.

bool CellCardImpl::likenbut [protected]

Definition at line 648 of file MCNPInput.cpp.

Definition at line 649 of file MCNPInput.cpp.

int CellCardImpl::material [protected]

Definition at line 638 of file MCNPInput.cpp.

double CellCardImpl::rho [protected]

Definition at line 639 of file MCNPInput.cpp.

Definition at line 644 of file MCNPInput.cpp.

int CellCardImpl::universe [protected]

Definition at line 646 of file MCNPInput.cpp.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines