cgma
|
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 Fill & | getFill () const |
virtual bool | isLattice () const |
virtual lattice_type_t | getLatticeType () const |
virtual const Lattice & | getLattice () 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 |
Definition at line 228 of file MCNPInput.cpp.
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(); }
CellCardImpl::~CellCardImpl | ( | ) | [inline] |
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] |
virtual const geom_list_t CellCardImpl::getGeom | ( | ) | const [inline, virtual] |
virtual int CellCardImpl::getIdent | ( | ) | const [inline, virtual] |
virtual const std::map<char,double>& CellCardImpl::getImportances | ( | ) | const [inline, virtual] |
virtual const Lattice& CellCardImpl::getLattice | ( | ) | const [inline, virtual] |
virtual lattice_type_t CellCardImpl::getLatticeType | ( | ) | const [inline, virtual] |
virtual int CellCardImpl::getMat | ( | ) | const [inline, virtual] |
virtual double CellCardImpl::getRho | ( | ) | const [inline, virtual] |
virtual const DataRef<Transform>& CellCardImpl::getTrcl | ( | ) | const [inline, virtual] |
virtual int CellCardImpl::getUniverse | ( | ) | const [inline, virtual] |
virtual bool CellCardImpl::hasFill | ( | ) | const [inline, virtual] |
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] |
Vector3d CellCardImpl::latticeVectorHelper | ( | Vector3d | difference_along_normal, |
Vector3d | v_dir | ||
) | [inline, protected] |
Definition at line 390 of file MCNPInput.cpp.
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.
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.
The | list 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(); } }
friend class InputDeck [friend] |
Definition at line 782 of file MCNPInput.cpp.
token_list_t CellCardImpl::data [protected] |
Definition at line 643 of file MCNPInput.cpp.
DataRef<Fill>* CellCardImpl::fill [protected] |
Definition at line 645 of file MCNPInput.cpp.
geom_list_t CellCardImpl::geom [protected] |
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.
lattice_type_t CellCardImpl::lat_type [protected] |
Definition at line 651 of file MCNPInput.cpp.
DataRef<Lattice>* CellCardImpl::lattice [protected] |
Definition at line 652 of file MCNPInput.cpp.
bool CellCardImpl::likenbut [protected] |
Definition at line 648 of file MCNPInput.cpp.
int CellCardImpl::likeness_cell_n [protected] |
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.
DataRef<Transform>* CellCardImpl::trcl [protected] |
Definition at line 644 of file MCNPInput.cpp.
int CellCardImpl::universe [protected] |
Definition at line 646 of file MCNPInput.cpp.