|
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.