/** * @brief Finds the Cell for which a LocalCoords object resides. * @details Finds the Cell that a LocalCoords object is located inside by * checking each of this Universe's Cells. Returns NULL if the * LocalCoords is not in any of the Cells. * @param coords a pointer to the LocalCoords of interest * @param universes a container of all of the Universes passed in by Geometry * @return a pointer the Cell where the LocalCoords is located */ Cell* Universe::findCell(LocalCoords* coords, std::map<int, Universe*> universes) { Cell* return_cell = NULL; std::map<int, Cell*>::iterator iter; /* Sets the LocalCoord type to UNIV at this level */ coords->setType(UNIV); /* Loop over all Cells in this Universe */ for (iter = _cells.begin(); iter != _cells.end(); ++iter) { Cell* cell = iter->second; if (cell->cellContainsCoords(coords)) { /* Set the Cell on this level */ coords->setCell(cell->getId()); /* MATERIAL type Cell - lowest level, terminate search for Cell */ if (cell->getType() == MATERIAL) { coords->setCell(cell->getId()); return_cell = cell; return return_cell; } /* FILL type Cell - Cell contains a Universe at a lower level * Update coords to next level and continue search */ else if (cell->getType() == FILL) { LocalCoords* next_coords; if (coords->getNext() == NULL) next_coords = new LocalCoords(coords->getX(), coords->getY()); else next_coords = coords->getNext(); CellFill* cell_fill = static_cast<CellFill*>(cell); int universe_id = cell_fill->getUniverseFillId(); next_coords->setUniverse(universe_id); Universe* univ = universes.at(universe_id); coords->setCell(cell->getId()); coords->setNext(next_coords); next_coords->setPrev(coords); if (univ->getType() == SIMPLE) return univ->findCell(next_coords, universes); else return static_cast<Lattice*>(univ)->findCell(next_coords, universes); } } } return return_cell; }
/** * @brief Finds the Cell within this Lattice that a LocalCoords is in. * @details This method first find the Lattice cell, then searches the * Universe inside that Lattice cell. If LocalCoords is outside * the bounds of the Lattice, this method will return NULL. * @param coords the LocalCoords of interest * @param universes a std::map of all Universes passed in from the geometry * @return a pointer to the Cell this LocalCoord is in or NULL */ Cell* Lattice::findCell(LocalCoords* coords, std::map<int, Universe*> universes) { /* Set the LocalCoord to be a LAT type at this level */ coords->setType(LAT); /* Compute the x and y indices for the Lattice cell this coord is in */ int lat_x = (int)floor((coords->getX() - _origin.getX()) / _width_x); int lat_y = (int)floor((coords->getY() - _origin.getY()) / _width_y); /* Check if the LocalCoord is on the Lattice boundaries and if so adjust * x or y Lattice cell indices */ if (fabs(fabs(coords->getX()) - _num_x*_width_x*0.5) < ON_LATTICE_CELL_THRESH) { if (coords->getX() > 0) lat_x = _num_x - 1; else lat_x = 0; } if (fabs(fabs(coords->getY()) - _num_y*_width_y*0.5) < ON_LATTICE_CELL_THRESH) { if (coords->getY() > 0) lat_y = _num_y - 1; else lat_y = 0; } /* If the indices are outside the bound of the Lattice */ if (lat_x < 0 || lat_x >= _num_x || lat_y < 0 || lat_y >= _num_y) { return NULL; } /* Compute local position of Point in the next level Universe */ double nextX = coords->getX() - (_origin.getX() + (lat_x + 0.5) * _width_x); double nextY = coords->getY() - (_origin.getY() + (lat_y + 0.5) * _width_y); /* Create a new LocalCoords object for the next level Universe */ LocalCoords* next_coords; if (coords->getNext() == NULL) next_coords = new LocalCoords(nextX, nextY); else next_coords = coords->getNext(); int universe_id = getUniverse(lat_x, lat_y)->getId(); Universe* univ = universes.at(universe_id); next_coords->setUniverse(universe_id); /* Set Lattice indices */ coords->setLattice(_id); coords->setLatticeX(lat_x); coords->setLatticeY(lat_y); coords->setNext(next_coords); next_coords->setPrev(coords); /* Search the next lowest level Universe for the Cell */ return univ->findCell(next_coords, universes); }