diff --git a/.circleci/config.yml b/.circleci/config.yml index c85027cb0..da5b46161 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ jobs: parameters: pyver: type: enum - enum: ["cp35-cp35m", "cp36-cp36m", "cp37-cp37m"] + enum: ["cp35-cp35m", "cp36-cp36m", "cp37-cp37m", "cp38-cp38"] steps: - setup_remote_docker - checkout @@ -42,8 +42,7 @@ jobs: name: Install auditwheel from source command: | git clone https://github.com/pypa/auditwheel.git - cd auditwheel && /opt/python/<< parameters.pyver >>/bin/python setup.py install - /opt/python/<< parameters.pyver >>/bin/pip install pyelftools + /opt/python/<< parameters.pyver >>/bin/python -m pip install ./auditwheel - run: name: Build E-Cell4 command: | @@ -66,3 +65,6 @@ workflows: - build: name: build_py37 pyver: cp37-cp37m + - build: + name: build_py38 + pyver: cp38-cp38 diff --git a/ecell4/core/HCPLatticeSpace.cpp b/ecell4/core/HCPLatticeSpace.cpp index 6ecd87cb8..524d56903 100644 --- a/ecell4/core/HCPLatticeSpace.cpp +++ b/ecell4/core/HCPLatticeSpace.cpp @@ -6,7 +6,8 @@ #include #endif -namespace ecell4 { +namespace ecell4 +{ #ifdef WIN32_MSC double rint(const double x) @@ -14,22 +15,20 @@ double rint(const double x) return boost::numeric::interval_lib::detail::rint(x); } -double round(const double x) -{ - return floor(x + 0.5); -} +double round(const double x) { return floor(x + 0.5); } #endif -void HCPLatticeSpace::set_lattice_properties(const Real3& edge_lengths, const bool is_periodic) +void HCPLatticeSpace::set_lattice_properties(const Real3 &edge_lengths, + const bool is_periodic) { - //XXX: derived from SpatiocyteStepper::setLatticeProperties() + // XXX: derived from SpatiocyteStepper::setLatticeProperties() HCP_L = voxel_radius_ / sqrt(3.0); HCP_X = voxel_radius_ * sqrt(8.0 / 3.0); // Lx - HCP_Y = voxel_radius_ * sqrt(3.0); // Ly + HCP_Y = voxel_radius_ * sqrt(3.0); // Ly - const Real& lengthX = edge_lengths[0]; - const Real& lengthY = edge_lengths[1]; - const Real& lengthZ = edge_lengths[2]; + const Real &lengthX = edge_lengths[0]; + const Real &lengthY = edge_lengths[1]; + const Real &lengthZ = edge_lengths[2]; col_size_ = (Integer)rint(lengthX / HCP_X); layer_size_ = (Integer)rint(lengthY / HCP_Y); @@ -37,20 +36,19 @@ void HCPLatticeSpace::set_lattice_properties(const Real3& edge_lengths, const bo if (is_periodic) { - // The number of voxels in each axis must be even for a periodic boundary. + // The number of voxels in each axis must be even for a periodic + // boundary. col_size_ = (col_size_ % 2 == 0 ? col_size_ : col_size_ + 1); layer_size_ = (layer_size_ % 2 == 0 ? layer_size_ : layer_size_ + 1); row_size_ = (row_size_ % 2 == 0 ? row_size_ : row_size_ + 1); } - edge_lengths_ = Real3( - col_size_ * HCP_X, - layer_size_ * HCP_Y, - row_size_ * voxel_radius_ * 2); + edge_lengths_ = Real3(col_size_ * HCP_X, layer_size_ * HCP_Y, + row_size_ * voxel_radius_ * 2); row_size_ += 2; layer_size_ += 2; col_size_ += 2; } -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/core/HCPLatticeSpace.hpp b/ecell4/core/HCPLatticeSpace.hpp index b632fbf83..d544dda4c 100644 --- a/ecell4/core/HCPLatticeSpace.hpp +++ b/ecell4/core/HCPLatticeSpace.hpp @@ -6,16 +6,14 @@ namespace ecell4 { -class HCPLatticeSpace - : public VoxelSpaceBase +class HCPLatticeSpace : public VoxelSpaceBase { public: - typedef VoxelSpaceBase base_type; public: - - HCPLatticeSpace(const Real3& edge_lengths, const Real& voxel_radius, const bool is_periodic) + HCPLatticeSpace(const Real3 &edge_lengths, const Real &voxel_radius, + const bool is_periodic) : base_type(voxel_radius) { set_lattice_properties(edge_lengths, is_periodic); @@ -26,99 +24,86 @@ class HCPLatticeSpace ; // do nothing } - virtual void reset(const Real3& edge_lengths, const Real& voxel_radius, const bool is_periodic) + virtual void reset(const Real3 &edge_lengths, const Real &voxel_radius, + const bool is_periodic) { voxel_radius_ = voxel_radius; set_lattice_properties(edge_lengths, is_periodic); } - void set_lattice_properties(const Real3& edge_lengths, const bool is_periodic); + void set_lattice_properties(const Real3 &edge_lengths, + const bool is_periodic); /** * Primitives */ - const Real3& edge_lengths() const - { - return edge_lengths_; - } + const Real3 &edge_lengths() const { return edge_lengths_; } - virtual const Integer col_size() const - { - return col_size_ - 2; - } + virtual const Integer col_size() const { return col_size_ - 2; } - virtual const Integer row_size() const - { - return row_size_ - 2; - } + virtual const Integer row_size() const { return row_size_ - 2; } - virtual const Integer layer_size() const - { - return layer_size_ - 2; - } + virtual const Integer layer_size() const { return layer_size_ - 2; } /** Coordinate transformations */ - coordinate_type global2coordinate(const Integer3& global) const + coordinate_type global2coordinate(const Integer3 &global) const { const Integer3 g(global.col + 1, global.row + 1, global.layer + 1); return g.row + row_size_ * (g.col + col_size_ * g.layer); } - Integer3 coordinate2global(const coordinate_type& coord) const + Integer3 coordinate2global(const coordinate_type &coord) const { const Integer NUM_COLROW(row_size_ * col_size_); const Integer LAYER(coord / NUM_COLROW); const Integer SURPLUS(coord - LAYER * NUM_COLROW); const Integer COL(SURPLUS / row_size_); const Integer3 global(COL, SURPLUS - COL * row_size_, LAYER); - const Integer3 retval( - global.col - 1, global.row - 1, global.layer - 1); + const Integer3 retval(global.col - 1, global.row - 1, global.layer - 1); return retval; } - Real3 coordinate2position(const coordinate_type& coord) const + Real3 coordinate2position(const coordinate_type &coord) const { return global2position(coordinate2global(coord)); } - coordinate_type position2coordinate(const Real3& pos) const + coordinate_type position2coordinate(const Real3 &pos) const { return global2coordinate(position2global(pos)); } - Real3 global2position(const Integer3& global) const + Real3 global2position(const Integer3 &global) const { // the center point of a voxel const Real3 pos( - global.col * HCP_X, - (global.col % 2) * HCP_L + HCP_Y * global.layer, - (global.row * 2 + (global.layer + global.col) % 2) - * voxel_radius_); + global.col * HCP_X, (global.col % 2) * HCP_L + HCP_Y * global.layer, + (global.row * 2 + (global.layer + global.col) % 2) * voxel_radius_); return pos; } - Integer3 position2global(const Real3& pos) const + Integer3 position2global(const Real3 &pos) const { const Integer col(round(pos[0] / HCP_X)); const Integer layer(round((pos[1] - (col % 2) * HCP_L) / HCP_Y)); - const Integer row(round( - (pos[2] / voxel_radius_ - ((layer + col) % 2)) / 2)); + const Integer row( + round((pos[2] / voxel_radius_ - ((layer + col) % 2)) / 2)); const Integer3 global(col, row, layer); return global; } - Integer num_neighbors(const coordinate_type& coord) const + Integer num_neighbors(const coordinate_type &coord) const { - if (!is_inside(coord)) return 0; + if (!is_inside(coord)) + return 0; return 12; } - coordinate_type periodic_transpose( - const coordinate_type& coord) const + coordinate_type periodic_transpose(const coordinate_type &coord) const { Integer3 global(coordinate2global(coord)); @@ -128,15 +113,15 @@ class HCPLatticeSpace global.col = global.col < 0 ? global.col + col_size() : global.col; global.row = global.row < 0 ? global.row + row_size() : global.row; - global.layer = global.layer < 0 ? global.layer + layer_size() : global.layer; + global.layer = + global.layer < 0 ? global.layer + layer_size() : global.layer; return global2coordinate(global); } protected: - - coordinate_type get_neighbor_( - const coordinate_type& coord, const Integer& nrand) const + coordinate_type get_neighbor_(const coordinate_type &coord, + const Integer &nrand) const { const Integer NUM_COLROW(col_size_ * row_size_); const Integer NUM_ROW(row_size_); @@ -177,24 +162,20 @@ class HCPLatticeSpace } public: - - bool is_in_range(const coordinate_type& coord) const + bool is_in_range(const coordinate_type &coord) const { return coord >= 0 && coord < row_size_ * col_size_ * layer_size_; } - virtual bool is_inside(const coordinate_type& coord) const + virtual bool is_inside(const coordinate_type &coord) const { const Integer3 global(coordinate2global(coord)); - return global.col >= 0 && global.col < col_size() - && global.row >= 0 && global.row < row_size() - && global.layer >= 0 && global.layer < layer_size(); + return global.col >= 0 && global.col < col_size() && global.row >= 0 && + global.row < row_size() && global.layer >= 0 && + global.layer < layer_size(); } - virtual Integer size() const - { - return row_size_ * col_size_ * layer_size_; - } + virtual Integer size() const { return row_size_ * col_size_ * layer_size_; } virtual Integer3 shape() const { @@ -207,12 +188,11 @@ class HCPLatticeSpace } protected: - Real3 edge_lengths_; Real HCP_L, HCP_X, HCP_Y; Integer row_size_, layer_size_, col_size_; }; -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_LATTICE_SPACE_BASE_HPP */ diff --git a/ecell4/core/LatticeSpaceCellListImpl.cpp b/ecell4/core/LatticeSpaceCellListImpl.cpp index dc1047896..5e2159293 100644 --- a/ecell4/core/LatticeSpaceCellListImpl.cpp +++ b/ecell4/core/LatticeSpaceCellListImpl.cpp @@ -1,22 +1,20 @@ #include "LatticeSpaceCellListImpl.hpp" #include "StructureType.hpp" - namespace ecell4 { -Integer LatticeSpaceCellListImpl::num_molecules(const Species& sp) const +Integer LatticeSpaceCellListImpl::num_molecules(const Species &sp) const { Integer count(0); SpeciesExpressionMatcher sexp(sp); - for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); - itr != molecule_pools_.end(); ++itr) + for (const auto &info : molecule_pools_) { - const Integer cnt(sexp.count((*itr).first)); + const Integer cnt(sexp.count(info.first)); if (cnt > 0) { - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp(info.second); count += vp->size() * cnt; } } @@ -24,19 +22,21 @@ Integer LatticeSpaceCellListImpl::num_molecules(const Species& sp) const } /* - * Change the Species and coordinate of a ParticleVoxel with ParticleID, pid, to - * v.species() and v.coordinate() respectively and return false. - * If no ParticleVoxel with pid is found, create a new ParticleVoxel at v.coordiante() and return ture. + * Change the Species and coordinate of a Voxel with ParticleID, pid, to + * species and coordinate respectively and return false. + * If no Voxel with pid is found, create a new Voxel at + * coordiante() and return true. */ -bool LatticeSpaceCellListImpl::update_voxel(const ParticleID& pid, ParticleVoxel v) +bool LatticeSpaceCellListImpl::update_voxel(const ParticleID &pid, + const Species &species, + const coordinate_type to_coord) { - const coordinate_type& to_coord(v.coordinate); if (!is_in_range(to_coord)) { throw NotSupported("Out of bounds"); } - boost::shared_ptr new_vp(get_voxel_pool(v)); //XXX: need MoleculeInfo + boost::shared_ptr new_vp(find_voxel_pool(species)); boost::shared_ptr dest_vp(get_voxel_pool_at(to_coord)); if (dest_vp != new_vp->location()) @@ -46,15 +46,15 @@ bool LatticeSpaceCellListImpl::update_voxel(const ParticleID& pid, ParticleVoxel if (pid != ParticleID()) { - const std::pair, coordinate_type> - target(__get_coordinate(pid)); - const coordinate_type& from_coord(target.second); + const std::pair, coordinate_type> target( + __get_coordinate(pid)); + const coordinate_type &from_coord(target.second); if (from_coord != -1) { // move target.first->remove_voxel_if_exists(from_coord); - //XXX: use location? + // XXX: use location? dest_vp->replace_voxel(to_coord, from_coord); new_vp->add_voxel(coordinate_id_pair_type(pid, to_coord)); @@ -80,8 +80,9 @@ bool LatticeSpaceCellListImpl::update_voxel(const ParticleID& pid, ParticleVoxel return true; } -bool LatticeSpaceCellListImpl::add_voxel( - const Species& sp, const ParticleID& pid, const coordinate_type& coord) +bool LatticeSpaceCellListImpl::add_voxel(const Species &sp, + const ParticleID &pid, + const coordinate_type &coord) { boost::shared_ptr vpool(find_voxel_pool(sp)); boost::shared_ptr location(get_voxel_pool_at(coord)); @@ -96,39 +97,41 @@ bool LatticeSpaceCellListImpl::add_voxel( return true; } -std::pair, LatticeSpaceCellListImpl::coordinate_type> - LatticeSpaceCellListImpl::__get_coordinate(const ParticleID& pid) +std::pair, + LatticeSpaceCellListImpl::coordinate_type> +LatticeSpaceCellListImpl::__get_coordinate(const ParticleID &pid) { - for (molecule_pool_map_type::iterator itr(molecule_pools_.begin()); - itr != molecule_pools_.end(); ++itr) + for (auto &info : molecule_pools_) { - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp(info.second); MoleculePool::container_type::const_iterator j(vp->find(pid)); if (j != vp->end()) { return std::make_pair(vp, (*j).coordinate); } } - return std::make_pair(boost::shared_ptr(), -1); //XXX: a bit dirty way + return std::make_pair(boost::shared_ptr(), + -1); // XXX: a bit dirty way } -std::pair, LatticeSpaceCellListImpl::coordinate_type> - LatticeSpaceCellListImpl::__get_coordinate(const ParticleID& pid) const +std::pair, + LatticeSpaceCellListImpl::coordinate_type> +LatticeSpaceCellListImpl::__get_coordinate(const ParticleID &pid) const { - for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); - itr != molecule_pools_.end(); ++itr) + for (const auto &info : molecule_pools_) { - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp(info.second); MoleculePool::container_type::const_iterator j(vp->find(pid)); if (j != vp->end()) { } } - return std::make_pair(boost::shared_ptr(), -1); //XXX: a bit dirty way + return std::make_pair(boost::shared_ptr(), + -1); // XXX: a bit dirty way } boost::shared_ptr LatticeSpaceCellListImpl::get_voxel_pool_at( - const LatticeSpaceCellListImpl::coordinate_type& coord) const + const LatticeSpaceCellListImpl::coordinate_type &coord) const { /** XXX: This may not work @@ -166,7 +169,7 @@ boost::shared_ptr LatticeSpaceCellListImpl::get_voxel_pool_at( // } // } - const cell_type& cell(matrix_[coordinate2index(coord)]); + const cell_type &cell(matrix_[coordinate2index(coord)]); if (cell.size() == 0) { return vacant_; @@ -181,8 +184,9 @@ boost::shared_ptr LatticeSpaceCellListImpl::get_voxel_pool_at( return vacant_; } -void LatticeSpaceCellListImpl::add_structure(const Species& sp, - const boost::shared_ptr& s, const std::string loc) +void LatticeSpaceCellListImpl::add_structure( + const Species &sp, const boost::shared_ptr &s, + const std::string loc) { make_structure_type(sp, loc); @@ -194,8 +198,8 @@ void LatticeSpaceCellListImpl::add_structure(const Species& sp, structures_.insert(std::make_pair(sp, s)); } -const boost::shared_ptr& LatticeSpaceCellListImpl::get_structure( - const Species& sp) const +const boost::shared_ptr & +LatticeSpaceCellListImpl::get_structure(const Species &sp) const { structure_container_type::const_iterator i(structures_.find(sp)); if (i == structures_.end()) @@ -205,8 +209,8 @@ const boost::shared_ptr& LatticeSpaceCellListImpl::get_structure( return (*i).second; } -const Shape::dimension_kind LatticeSpaceCellListImpl::get_structure_dimension( - const Species& sp) const +const Shape::dimension_kind +LatticeSpaceCellListImpl::get_structure_dimension(const Species &sp) const { structure_container_type::const_iterator i(structures_.find(sp)); if (i == structures_.end()) @@ -216,4 +220,4 @@ const Shape::dimension_kind LatticeSpaceCellListImpl::get_structure_dimension( return (*i).second->dimension(); } -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/core/LatticeSpaceCellListImpl.hpp b/ecell4/core/LatticeSpaceCellListImpl.hpp index a0130a0d0..030f67467 100644 --- a/ecell4/core/LatticeSpaceCellListImpl.hpp +++ b/ecell4/core/LatticeSpaceCellListImpl.hpp @@ -7,8 +7,8 @@ // #include #include -#include "comparators.hpp" #include "HCPLatticeSpace.hpp" +#include "comparators.hpp" namespace ecell4 { @@ -18,40 +18,39 @@ inline unsigned int ceilint(const unsigned int x, const unsigned int y) return x / y + (x % y != 0); } -class LatticeSpaceCellListImpl - : public HCPLatticeSpace +class LatticeSpaceCellListImpl : public HCPLatticeSpace { public: - typedef HCPLatticeSpace base_type; typedef base_type::coordinate_id_pair_type coordinate_id_pair_type; typedef base_type::coordinate_type coordinate_type; - typedef std::vector, coordinate_type> > + typedef std::vector< + std::pair, coordinate_type>> cell_type; typedef std::vector matrix_type; - typedef std::map > structure_container_type; + typedef std::map> + structure_container_type; protected: - - typedef utils::get_mapper_mf< - Species, boost::shared_ptr >::type voxel_pool_map_type; - typedef utils::get_mapper_mf< - Species, boost::shared_ptr >::type molecule_pool_map_type; + typedef utils::get_mapper_mf>::type + voxel_pool_map_type; + typedef utils::get_mapper_mf>::type + molecule_pool_map_type; // typedef std::map< // Species, boost::shared_ptr > voxel_pool_map_type; // typedef std::map< // Species, boost::shared_ptr > molecule_pool_map_type; public: - - LatticeSpaceCellListImpl( - const Real3& edge_lengths, const Real& voxel_radius, - const Integer3& matrix_sizes, const bool is_periodic = true) - : base_type(edge_lengths, voxel_radius, is_periodic), is_periodic_(is_periodic), - matrix_sizes_(matrix_sizes), - matrix_(matrix_sizes_[0] * matrix_sizes_[1] * matrix_sizes_[2]) + LatticeSpaceCellListImpl(const Real3 &edge_lengths, + const Real &voxel_radius, + const Integer3 &matrix_sizes, + const bool is_periodic = true) + : base_type(edge_lengths, voxel_radius, is_periodic), + is_periodic_(is_periodic), matrix_sizes_(matrix_sizes), + matrix_(matrix_sizes_[0] * matrix_sizes_[1] * matrix_sizes_[2]) { cell_sizes_[0] = ceilint(col_size_, matrix_sizes_[0]); cell_sizes_[1] = ceilint(row_size_, matrix_sizes_[1]); @@ -63,9 +62,9 @@ class LatticeSpaceCellListImpl } border_ = boost::shared_ptr( - new MoleculePool(Species("Border", voxel_radius_, 0), vacant_)); + new MoleculePool(Species("Border", voxel_radius_, 0), vacant_)); periodic_ = boost::shared_ptr( - new MoleculePool(Species("Periodic", voxel_radius_, 0), vacant_)); + new MoleculePool(Species("Periodic", voxel_radius_, 0), vacant_)); } virtual ~LatticeSpaceCellListImpl() {} @@ -73,20 +72,25 @@ class LatticeSpaceCellListImpl /** */ - inline matrix_type::size_type coordinate2index(const coordinate_type& coord) const + inline matrix_type::size_type + coordinate2index(const coordinate_type &coord) const { return global2index(coordinate2global(coord)); } - inline matrix_type::size_type global2index(const Integer3& g) const + inline matrix_type::size_type global2index(const Integer3 &g) const { - return (g.col / cell_sizes_[0]) + matrix_sizes_[0] * ((g.row / cell_sizes_[1]) + matrix_sizes_[1] * (g.layer / cell_sizes_[2])); + return (g.col / cell_sizes_[0]) + + matrix_sizes_[0] * + ((g.row / cell_sizes_[1]) + + matrix_sizes_[1] * (g.layer / cell_sizes_[2])); } - cell_type::iterator find_from_cell( - const coordinate_type& coord, cell_type& cell) + cell_type::iterator find_from_cell(const coordinate_type &coord, + cell_type &cell) { - return std::find_if(cell.begin(), cell.end(), + return std::find_if( + cell.begin(), cell.end(), utils::pair_second_element_unary_predicator< boost::shared_ptr, coordinate_type>(coord)); // cell_type::iterator i(cell.begin()); @@ -100,10 +104,11 @@ class LatticeSpaceCellListImpl // return i; } - cell_type::const_iterator find_from_cell( - const coordinate_type& coord, const cell_type& cell) const + cell_type::const_iterator find_from_cell(const coordinate_type &coord, + const cell_type &cell) const { - return std::find_if(cell.begin(), cell.end(), + return std::find_if( + cell.begin(), cell.end(), utils::pair_second_element_unary_predicator< boost::shared_ptr, coordinate_type>(coord)); // cell_type::const_iterator i(cell.begin()); @@ -117,9 +122,10 @@ class LatticeSpaceCellListImpl // return i; } - void update_matrix(const coordinate_type& coord, boost::shared_ptr vp) + void update_matrix(const coordinate_type &coord, + boost::shared_ptr vp) { - cell_type& cell(matrix_[coordinate2index(coord)]); + cell_type &cell(matrix_[coordinate2index(coord)]); cell_type::iterator i(find_from_cell(coord, cell)); if (i != cell.end()) @@ -143,15 +149,15 @@ class LatticeSpaceCellListImpl } } - void update_matrix(const coordinate_type& from_coord, - const coordinate_type& to_coord, - boost::shared_ptr vp) + void update_matrix(const coordinate_type &from_coord, + const coordinate_type &to_coord, + boost::shared_ptr vp) { const matrix_type::size_type from_idx(coordinate2index(from_coord)), to_idx(coordinate2index(to_coord)); if (from_idx == to_idx) { - cell_type& cell(matrix_[from_idx]); + cell_type &cell(matrix_[from_idx]); cell_type::iterator i(find_from_cell(from_coord, cell)); if (i == cell.end()) { @@ -162,7 +168,7 @@ class LatticeSpaceCellListImpl } else { - cell_type& cell(matrix_[from_idx]); + cell_type &cell(matrix_[from_idx]); cell_type::iterator i(find_from_cell(from_coord, cell)); if (i == cell.end()) { @@ -178,7 +184,7 @@ class LatticeSpaceCellListImpl std::cout << "=====================" << std::endl; for (matrix_type::size_type i(0); i != matrix_.size(); ++i) { - cell_type& c(matrix_[i]); + cell_type &c(matrix_[i]); if (c.size() == 0) { continue; @@ -194,43 +200,15 @@ class LatticeSpaceCellListImpl std::cout << "=====================" << std::endl; } - /** - */ + virtual bool update_voxel(const ParticleID &pid, const Species &species, + const coordinate_type coordinate); + virtual bool add_voxel(const Species &sp, const ParticleID &pid, + const coordinate_type &coord); - // /** - // * Change the Species at v.coordinate() to v.species. - // * The ParticleID must be kept after this update. - // */ - // virtual void update_voxel(const ParticleVoxel& v) - // { - // const coordinate_type coord(v.coordinate()); - // // VoxelPool* src_vp(get_voxel_pool(coord)); - // VoxelPool* src_vp(find_voxel_pool(coord)); - // VoxelPool* new_vp(get_voxel_pool(v)); - - // if (src_vp->with_voxels() != new_vp->with_voxels()) - // { - // throw NotSupported("ParticleID is needed/lost."); - // } - - // new_vp->add_voxel(src_vp->pop(coord)); - // update_matrix(coord, new_vp); - // } - - virtual bool update_voxel(const ParticleID& pid, ParticleVoxel v); - virtual bool add_voxel(const Species& sp, const ParticleID& pid, const coordinate_type& coord); - - virtual std::pair get_voxel_at(const coordinate_type& coord) const + virtual bool remove_voxel(const ParticleID &pid) { - boost::shared_ptr vp(get_voxel_pool_at(coord)); - return std::make_pair( - vp->get_particle_id(coord), - ParticleVoxel(vp->species(), coord, vp->radius(), vp->D(), get_location_serial(vp))); - } - - virtual bool remove_voxel(const ParticleID& pid) - { - std::pair, coordinate_type> target(__get_coordinate(pid)); + std::pair, coordinate_type> target( + __get_coordinate(pid)); if (target.second != -1) { boost::shared_ptr vp(target.first); @@ -240,14 +218,15 @@ class LatticeSpaceCellListImpl return false; } - vp->location()->add_voxel(coordinate_id_pair_type(ParticleID(), coord)); + vp->location()->add_voxel( + coordinate_id_pair_type(ParticleID(), coord)); update_matrix(coord, vp->location()); return true; } return false; } - virtual bool remove_voxel(const coordinate_type& coord) + virtual bool remove_voxel(const coordinate_type &coord) { boost::shared_ptr vp(get_voxel_pool_at(coord)); if (vp->is_vacant()) @@ -264,9 +243,8 @@ class LatticeSpaceCellListImpl return true; } - virtual bool move( - const coordinate_type& src, const coordinate_type& dest, - const std::size_t candidate=0) + virtual bool move(const coordinate_type &src, const coordinate_type &dest, + const std::size_t candidate = 0) { coordinate_type tmp_dest(dest); if (src == tmp_dest) @@ -310,7 +288,8 @@ class LatticeSpaceCellListImpl return true; } - virtual bool can_move(const coordinate_type& src, const coordinate_type& dest) const + virtual bool can_move(const coordinate_type &src, + const coordinate_type &dest) const { if (src == dest) { @@ -338,28 +317,26 @@ class LatticeSpaceCellListImpl return (dest_vp == src_vp->location()); } - virtual const Particle particle_at(const coordinate_type& coord) const - { - boost::shared_ptr vp(get_voxel_pool_at(coord)); - return Particle( - vp->species(), coordinate2position(coord), vp->radius(), vp->D()); - } + boost::shared_ptr + get_voxel_pool_at(const coordinate_type &coord) const; - boost::shared_ptr get_voxel_pool_at(const coordinate_type& coord) const; - - coordinate_type get_neighbor( - const coordinate_type& coord, const Integer& nrand) const + coordinate_type get_neighbor(const coordinate_type &coord, + const Integer &nrand) const { coordinate_type const dest = get_neighbor_(coord, nrand); - return (!is_periodic_ || is_inside(dest) ? dest : periodic_transpose(dest)); + return (!is_periodic_ || is_inside(dest) ? dest + : periodic_transpose(dest)); } - virtual void add_structure(const Species& sp, - const boost::shared_ptr& s, const std::string loc); - virtual const boost::shared_ptr& get_structure(const Species& sp) const; - virtual const Shape::dimension_kind get_structure_dimension(const Species& sp) const; + virtual void add_structure(const Species &sp, + const boost::shared_ptr &s, + const std::string loc); + virtual const boost::shared_ptr & + get_structure(const Species &sp) const; + virtual const Shape::dimension_kind + get_structure_dimension(const Species &sp) const; - virtual Integer num_molecules(const Species& sp) const; + virtual Integer num_molecules(const Species &sp) const; /** */ @@ -368,29 +345,29 @@ class LatticeSpaceCellListImpl /* * HDF5 Save */ - void save_hdf5(H5::Group* root) const + void save_hdf5(H5::Group *root) const { // save_lattice_space(*this, root, "LatticeSpaceCellListImpl"); - throw NotSupported("LatticeSpaceCellListImpl::save_hdf5 is not supported yet."); + throw NotSupported( + "LatticeSpaceCellListImpl::save_hdf5 is not supported yet."); } - void load_hdf5(const H5::Group& root) + void load_hdf5(const H5::Group &root) { // load_lattice_space(root, this); // load_lattice_space(root, this, "LatticeSpaceCellListImpl"); - throw NotSupported("LatticeSpaceCellListImpl::load_hdf5 is not supported yet."); + throw NotSupported( + "LatticeSpaceCellListImpl::load_hdf5 is not supported yet."); } #endif protected: - std::pair, coordinate_type> - __get_coordinate(const ParticleID& pid); + __get_coordinate(const ParticleID &pid); std::pair, coordinate_type> - __get_coordinate(const ParticleID& pid) const; + __get_coordinate(const ParticleID &pid) const; protected: - bool is_periodic_; boost::shared_ptr border_; @@ -401,6 +378,6 @@ class LatticeSpaceCellListImpl structure_container_type structures_; }; -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_LATTICE_SPACE_CELL_LIST_IMPL_HPP */ diff --git a/ecell4/core/LatticeSpaceHDF5Writer.hpp b/ecell4/core/LatticeSpaceHDF5Writer.hpp index d5d24d70f..4f392587b 100644 --- a/ecell4/core/LatticeSpaceHDF5Writer.hpp +++ b/ecell4/core/LatticeSpaceHDF5Writer.hpp @@ -1,42 +1,41 @@ #ifndef ECELL4_LATTICE_SPACE_HDF5_WRITER_HPP #define ECELL4_LATTICE_SPACE_HDF5_WRITER_HPP +#include +#include +#include #include #include -#include #include -#include -#include -#include +#include -#include #include +#include -#include "types.hpp" -#include "Species.hpp" -#include "ParticleVoxel.hpp" -#include "VoxelPool.hpp" #include "MoleculePool.hpp" +#include "Species.hpp" #include "StructureType.hpp" #include "VacantType.hpp" +#include "VoxelPool.hpp" #include "VoxelSpaceBase.hpp" +#include "VoxelView.hpp" +#include "types.hpp" -#include "Space.hpp" // just for Space::space_kind - +#include "Space.hpp" // just for Space::space_kind namespace ecell4 { struct LatticeSpaceHDF5Traits { - struct h5_species_struct { - double radius; - double D; + struct h5_species_struct + { char location[32]; uint32_t is_structure; }; - struct h5_voxel_struct { + struct h5_voxel_struct + { uint32_t lot; uint32_t serial; uint64_t coordinate; @@ -45,9 +44,9 @@ struct LatticeSpaceHDF5Traits static H5::CompType get_voxel_comp() { H5::CompType voxel_comp_type(sizeof(h5_voxel_struct)); -#define INSERT_MEMBER(member, type) \ - H5Tinsert(voxel_comp_type.getId(), #member,\ - HOFFSET(h5_voxel_struct, member), type.getId()) +#define INSERT_MEMBER(member, type) \ + H5Tinsert(voxel_comp_type.getId(), #member, \ + HOFFSET(h5_voxel_struct, member), type.getId()) INSERT_MEMBER(lot, H5::PredType::NATIVE_INT); INSERT_MEMBER(serial, H5::PredType::NATIVE_INT); INSERT_MEMBER(coordinate, H5::PredType::STD_I64LE); @@ -55,68 +54,69 @@ struct LatticeSpaceHDF5Traits return voxel_comp_type; } - static void save_voxel_pool(const VoxelPool* mtb, - std::vector > voxels, H5::Group* group) + static void save_voxel_pool(const VoxelPool *mtb, + std::vector voxels, H5::Group *group) { const Species species(mtb->species()); boost::scoped_ptr mtgroup( - new H5::Group(group->createGroup(species.serial().c_str()))); + new H5::Group(group->createGroup(species.serial().c_str()))); h5_species_struct property; - property.radius = mtb->radius(); - property.D = mtb->D(); boost::shared_ptr loc(mtb->location()); // if (loc->is_vacant()) // property.location = H5std_string(""); // else - // property.location = H5std_string(loc->species().serial().c_str()); + // property.location = + // H5std_string(loc->species().serial().c_str()); if (loc->is_vacant()) std::strcpy(property.location, ""); else std::strcpy(property.location, loc->species().serial().c_str()); property.is_structure = mtb->is_structure() ? 1 : 0; - mtgroup->createAttribute("radius", H5::PredType::IEEE_F64LE, H5::DataSpace(H5S_SCALAR) - ).write(H5::PredType::IEEE_F64LE, &property.radius); - mtgroup->createAttribute("D", H5::PredType::IEEE_F64LE, H5::DataSpace(H5S_SCALAR) - ).write(H5::PredType::IEEE_F64LE, &property.D); - mtgroup->createAttribute("location", H5::StrType(H5::PredType::C_S1, 32), H5::DataSpace(H5S_SCALAR) - ).write(H5::StrType(H5::PredType::C_S1, 32), &property.location); - // mtgroup->createAttribute("location", H5::StrType(0, H5T_VARIABLE), H5::DataSpace(H5S_SCALAR) + mtgroup + ->createAttribute("location", H5::StrType(H5::PredType::C_S1, 32), + H5::DataSpace(H5S_SCALAR)) + .write(H5::StrType(H5::PredType::C_S1, 32), &property.location); + // mtgroup->createAttribute("location", H5::StrType(0, H5T_VARIABLE), + // H5::DataSpace(H5S_SCALAR) // ).write(H5::StrType(0, H5T_VARIABLE), &property.location); - mtgroup->createAttribute("is_structure", H5::PredType::STD_I32LE, H5::DataSpace(H5S_SCALAR) - ).write(H5::PredType::STD_I32LE, &property.is_structure); + mtgroup + ->createAttribute("is_structure", H5::PredType::STD_I32LE, + H5::DataSpace(H5S_SCALAR)) + .write(H5::PredType::STD_I32LE, &property.is_structure); // Save voxels const Integer num_voxels(voxels.size()); std::size_t vidx(0); - boost::scoped_array h5_voxel_array(new h5_voxel_struct[num_voxels]); - for (std::vector >::const_iterator itr(voxels.begin()); - itr != voxels.end(); ++itr) + boost::scoped_array h5_voxel_array( + new h5_voxel_struct[num_voxels]); + for (const auto &view : voxels) { - h5_voxel_array[vidx].lot = (*itr).first.lot(); - h5_voxel_array[vidx].serial = (*itr).first.serial(); - h5_voxel_array[vidx].coordinate = (*itr).second.coordinate; + h5_voxel_array[vidx].lot = view.pid.lot(); + h5_voxel_array[vidx].serial = view.pid.serial(); + h5_voxel_array[vidx].coordinate = view.voxel; ++vidx; } H5::CompType voxel_comp_type(get_voxel_comp()); - hsize_t dims[] = {(hsize_t) num_voxels}; - H5::DataSpace dspace(/* RANK= */1, dims); + hsize_t dims[] = {(hsize_t)num_voxels}; + H5::DataSpace dspace(/* RANK= */ 1, dims); boost::scoped_ptr dset(new H5::DataSet( mtgroup->createDataSet("voxels", voxel_comp_type, dspace))); dset->write(h5_voxel_array.get(), dset->getDataType()); } - template - static void save_voxel_pool_recursively(const Species& location, - std::multimap& location_map, - Tspace_& space, H5::Group* root) + template + static void save_voxel_pool_recursively( + const Species &location, + std::multimap &location_map, Tspace_ &space, + H5::Group *root) { - std::multimap::iterator itr; + std::multimap::iterator itr; while ((itr = location_map.find(location)) != location_map.end()) { - const VoxelPool* mtb((*itr).second); + const VoxelPool *mtb((*itr).second); const Species species(mtb->species()); save_voxel_pool(mtb, space.list_voxels_exact(species), root); save_voxel_pool_recursively(species, location_map, space, root); @@ -124,8 +124,10 @@ struct LatticeSpaceHDF5Traits } } - static void sort_by_location(std::multimap location_map, - std::vector& species, const std::string location="") + static void + sort_by_location(std::multimap location_map, + std::vector &species, + const std::string location = "") { std::multimap::iterator itr; while ((itr = location_map.find(location)) != location_map.end()) @@ -136,27 +138,28 @@ struct LatticeSpaceHDF5Traits location_map.erase(itr); } } - }; -template -void save_lattice_space(const Tspace_& space, H5::Group* root, const std::string& impl = "") +template +void save_lattice_space(const Tspace_ &space, H5::Group *root, + const std::string &impl = "") { typedef LatticeSpaceHDF5Traits traits_type; - boost::scoped_ptr spgroup(new H5::Group(root->createGroup("species"))); + boost::scoped_ptr spgroup( + new H5::Group(root->createGroup("species"))); const std::vector species(space.list_species()); - std::multimap location_map; - for (std::vector::const_iterator itr(species.begin()); - itr != species.end(); ++itr) + std::multimap location_map; + for (const auto &sp : species) { - boost::shared_ptr mtb(space.find_voxel_pool(*itr)); + boost::shared_ptr mtb(space.find_voxel_pool(sp)); Species location(mtb->location()->species()); - location_map.insert(std::make_pair(location, mtb.get())); // XXX: remove .get() + location_map.insert( + std::make_pair(location, mtb.get())); // XXX: remove .get() } - traits_type::save_voxel_pool_recursively(space.vacant()->species(), - location_map, space, spgroup.get()); + traits_type::save_voxel_pool_recursively( + space.vacant()->species(), location_map, space, spgroup.get()); const hsize_t dims[] = {3}; const H5::ArrayType lengths_type(H5::PredType::NATIVE_DOUBLE, 1, dims); @@ -165,15 +168,15 @@ void save_lattice_space(const Tspace_& space, H5::Group* root, const std::string const uint32_t space_type(static_cast(Space::LATTICE)); const double t(space.t()); const double voxel_radius(space.voxel_radius()); - const uint32_t is_periodic(space.is_periodic()? 1 : 0); + const uint32_t is_periodic(space.is_periodic() ? 1 : 0); double edge_lengths[] = {lengths[0], lengths[1], lengths[2]}; char implementation[32]; std::strcpy(implementation, impl.c_str()); -#define CREATE_ATTRIBUTE(attribute, type) \ - root->createAttribute(#attribute, type,\ - H5::DataSpace(H5S_SCALAR)).write(type, &attribute) +#define CREATE_ATTRIBUTE(attribute, type) \ + root->createAttribute(#attribute, type, H5::DataSpace(H5S_SCALAR)) \ + .write(type, &attribute) CREATE_ATTRIBUTE(space_type, H5::PredType::STD_I32LE); CREATE_ATTRIBUTE(t, H5::PredType::IEEE_F64LE); CREATE_ATTRIBUTE(voxel_radius, H5::PredType::IEEE_F64LE); @@ -184,8 +187,9 @@ void save_lattice_space(const Tspace_& space, H5::Group* root, const std::string #undef CREATE_ATTRIBUTE } -template -void load_lattice_space(const H5::Group& root, Tspace_* space, const std::string& implementation = "") +template +void load_lattice_space(const H5::Group &root, Tspace_ *space, + const std::string &implementation = "") { typedef LatticeSpaceHDF5Traits traits_type; @@ -198,31 +202,33 @@ void load_lattice_space(const H5::Group& root, Tspace_* space, const std::string char impl_C[32]; // std::string impl = ""; -#define OPEN_ATTRIBUTE(attribute, type) \ +#define OPEN_ATTRIBUTE(attribute, type) \ root.openAttribute(#attribute).read(type, &attribute) OPEN_ATTRIBUTE(space_type, H5::PredType::STD_I32LE); OPEN_ATTRIBUTE(t, H5::PredType::IEEE_F64LE); OPEN_ATTRIBUTE(voxel_radius, H5::PredType::IEEE_F64LE); - OPEN_ATTRIBUTE(edge_lengths, H5::ArrayType(H5::PredType::NATIVE_DOUBLE, 1, dims)); + OPEN_ATTRIBUTE(edge_lengths, + H5::ArrayType(H5::PredType::NATIVE_DOUBLE, 1, dims)); OPEN_ATTRIBUTE(is_periodic, H5::PredType::STD_I32LE); #undef OPEN_ATTRIBUTE // if (root.attrExists("implementation")) // root.openAttribute("implementation").read( - // H5::StrType(0, H5T_VARIABLE), impl); //XXX: '&' is not needed for HDF5std_string + // H5::StrType(0, H5T_VARIABLE), impl); //XXX: '&' is not needed + // for HDF5std_string // if (root.attrExists("implementation")) // root.openAttribute("implementation").read( // H5::StrType(H5::PredType::C_S1, 32), impl_C); try { - root.openAttribute("implementation").read( - H5::StrType(H5::PredType::C_S1, 32), impl_C); + root.openAttribute("implementation") + .read(H5::StrType(H5::PredType::C_S1, 32), impl_C); } - catch (const H5::AttributeIException& e) + catch (const H5::AttributeIException &e) { // XXX: H5::Location::attrExists is not available in the old version - ; // no attribute exists. do nothing + ; // no attribute exists. do nothing } const std::string impl(impl_C); @@ -230,7 +236,8 @@ void load_lattice_space(const H5::Group& root, Tspace_* space, const std::string if (implementation != "" && implementation != impl) { std::ostringstream oss; - oss << "Implementation mismatch between LatticeSpaces given and saved in the HDF5 ['" + oss << "Implementation mismatch between LatticeSpaces given and saved " + "in the HDF5 ['" << implementation << "' != '" << impl << "']." << std::endl; throw NotSupported(oss.str()); } @@ -239,11 +246,12 @@ void load_lattice_space(const H5::Group& root, Tspace_* space, const std::string space->reset(edge_lengths, voxel_radius, (is_periodic != 0)); std::map struct_map; - std::map > > voxels_map; + std::map>> voxels_map; std::multimap location_map; std::map > > > tmp_map; + std::vector>>> + tmp_map; H5::Group spgroup(root.openGroup("species")); char name_C[32 + 1]; @@ -252,8 +260,9 @@ void load_lattice_space(const H5::Group& root, Tspace_* space, const std::string // const H5std_string name = spgroup.getObjnameByIdx(idx); // H5::Group group(spgroup.openGroup(name.c_str())); - memset(name_C, 0, 32 + 1); // clear buffer - H5Lget_name_by_idx(spgroup.getLocId(), ".", H5_INDEX_NAME, H5_ITER_INC, idx, name_C, 32, H5P_DEFAULT); + memset(name_C, 0, 32 + 1); // clear buffer + H5Lget_name_by_idx(spgroup.getLocId(), ".", H5_INDEX_NAME, H5_ITER_INC, + idx, name_C, 32, H5P_DEFAULT); H5::Group group(spgroup.openGroup(name_C)); const std::string name(name_C); Species species(name); @@ -271,34 +280,38 @@ void load_lattice_space(const H5::Group& root, Tspace_* space, const std::string // H5::DataType dtype = attr.getDataType(); // attr.read(dtype, &property); - group.openAttribute("radius").read(H5::PredType::IEEE_F64LE, &property.radius); - group.openAttribute("D").read(H5::PredType::IEEE_F64LE, &property.D); - // group.openAttribute("location").read(H5::StrType(0, H5T_VARIABLE), property.location); //XXX: NEVER use "&" for H5std_string when reading. - group.openAttribute("location").read(H5::StrType(H5::PredType::C_S1, 32), property.location); - group.openAttribute("is_structure").read(H5::PredType::STD_I32LE, &property.is_structure); + // group.openAttribute("location").read(H5::StrType(0, H5T_VARIABLE), + // property.location); //XXX: NEVER use "&" for H5std_string when + // reading. + group.openAttribute("location") + .read(H5::StrType(H5::PredType::C_S1, 32), property.location); + group.openAttribute("is_structure") + .read(H5::PredType::STD_I32LE, &property.is_structure); - // std::cout << "load_property(" << name << "," << property.radius << "," << property.D << "," << property.location << ");" << std::endl; + // std::cout << "load_property(" << name << "," << property.radius << + // "," << property.D << "," << property.location << ");" << std::endl; struct_map.insert(std::make_pair(species, property)); - location_map.insert(std::make_pair(std::string(property.location), species)); + location_map.insert( + std::make_pair(std::string(property.location), species)); // location_map.insert(std::make_pair(property.location, species)); H5::DataSet voxel_dset(group.openDataSet("voxels")); const unsigned int num_voxels( voxel_dset.getSpace().getSimpleExtentNpoints()); boost::scoped_array h5_voxel_array( - new traits_type::h5_voxel_struct[num_voxels]); - voxel_dset.read( - h5_voxel_array.get(), traits_type::get_voxel_comp()); + new traits_type::h5_voxel_struct[num_voxels]); + voxel_dset.read(h5_voxel_array.get(), traits_type::get_voxel_comp()); voxel_dset.close(); group.close(); - std::vector > voxels; + std::vector> voxels; for (unsigned int idx(0); idx < num_voxels; ++idx) { voxels.push_back(std::make_pair( - ParticleID(std::make_pair(h5_voxel_array[idx].lot, h5_voxel_array[idx].serial)), - h5_voxel_array[idx].coordinate)); + ParticleID(std::make_pair(h5_voxel_array[idx].lot, + h5_voxel_array[idx].serial)), + h5_voxel_array[idx].coordinate)); } voxels_map.insert(std::make_pair(species, voxels)); } @@ -306,20 +319,20 @@ void load_lattice_space(const H5::Group& root, Tspace_* space, const std::string std::vector sp_list; traits_type::sort_by_location(location_map, sp_list); - for (std::vector::iterator itr(sp_list.begin()); - itr != sp_list.end(); ++itr) + for (const auto &species : sp_list) { - Species species(*itr); - traits_type::h5_species_struct property((*struct_map.find(species)).second); - std::vector > voxels((*voxels_map.find(species)).second); + traits_type::h5_species_struct property( + (*struct_map.find(species)).second); + std::vector> voxels( + (*voxels_map.find(species)).second); if (property.is_structure == 0) - space->make_molecular_type(species, property.radius, property.D, std::string(property.location)); + space->make_molecular_type(species, std::string(property.location)); else space->make_structure_type(species, std::string(property.location)); space->add_voxels(species, voxels); } } -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_LATTICE_SPACE_HDF5_WRITER_HPP */ diff --git a/ecell4/core/LatticeSpaceVectorImpl.cpp b/ecell4/core/LatticeSpaceVectorImpl.cpp index 6723ca222..88ff62811 100644 --- a/ecell4/core/LatticeSpaceVectorImpl.cpp +++ b/ecell4/core/LatticeSpaceVectorImpl.cpp @@ -1,22 +1,24 @@ #include "Context.hpp" +#include "LatticeSpaceVectorImpl.hpp" #include "MoleculePool.hpp" -#include "VacantType.hpp" #include "StructureType.hpp" -#include "LatticeSpaceVectorImpl.hpp" +#include "VacantType.hpp" -namespace ecell4 { +namespace ecell4 +{ typedef LatticeSpaceVectorImpl::coordinate_type coordinate_type; -LatticeSpaceVectorImpl::LatticeSpaceVectorImpl( - const Real3& edge_lengths, const Real& voxel_radius, - const bool is_periodic) : - base_type(edge_lengths, voxel_radius, is_periodic), is_periodic_(is_periodic) +LatticeSpaceVectorImpl::LatticeSpaceVectorImpl(const Real3 &edge_lengths, + const Real &voxel_radius, + const bool is_periodic) + : base_type(edge_lengths, voxel_radius, is_periodic), + is_periodic_(is_periodic) { border_ = boost::shared_ptr( - new MoleculePool(Species("Border", voxel_radius_, 0), vacant_)); + new MoleculePool(Species("Border", voxel_radius_, 0), vacant_)); periodic_ = boost::shared_ptr( - new MoleculePool(Species("Periodic", voxel_radius, 0), vacant_)); + new MoleculePool(Species("Periodic", voxel_radius, 0), vacant_)); initialize_voxels(is_periodic_); } @@ -39,12 +41,14 @@ void LatticeSpaceVectorImpl::initialize_voxels(const bool is_periodic) if (is_periodic) { voxels_.push_back(periodic_); - periodic_->add_voxel(coordinate_id_pair_type(ParticleID(), coord)); + periodic_->add_voxel( + coordinate_id_pair_type(ParticleID(), coord)); } else { voxels_.push_back(border_); - border_->add_voxel(coordinate_id_pair_type(ParticleID(), coord)); + border_->add_voxel( + coordinate_id_pair_type(ParticleID(), coord)); } } else @@ -60,55 +64,38 @@ Integer LatticeSpaceVectorImpl::num_species() const return voxel_pools_.size() + molecule_pools_.size(); } -std::pair -LatticeSpaceVectorImpl::get_voxel_at(const coordinate_type& coord) const +bool LatticeSpaceVectorImpl::update_structure(const Particle &p) { - boost::shared_ptr vp(voxels_.at(coord)); - - return std::make_pair( - vp->get_particle_id(coord), - ParticleVoxel(vp->species(), - coord, - vp->radius(), - vp->D(), - get_location_serial(vp))); -} - -bool LatticeSpaceVectorImpl::update_structure(const Particle& p) -{ - //XXX: Particle does not have a location. - ParticleVoxel v(p.species(), position2coordinate(p.position()), p.radius(), p.D()); - return update_voxel(ParticleID(), v); + return update_voxel(ParticleID(), p.species(), + position2coordinate(p.position())); } /* * original methods */ -const Species& LatticeSpaceVectorImpl::find_species(std::string name) const +const Species &LatticeSpaceVectorImpl::find_species(std::string name) const { - for (voxel_pool_map_type::const_iterator itr(voxel_pools_.begin()); - itr != voxel_pools_.end(); ++itr) + for (const auto &pool : voxel_pools_) { - if ((*itr).first.serial() == name) + if (pool.first.serial() == name) { - return (*itr).first; + return pool.first; } } - for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); - itr != molecule_pools_.end(); ++itr) + for (const auto &pool : molecule_pools_) { - if ((*itr).first.serial() == name) + if (pool.first.serial() == name) { - return (*itr).first; + return pool.first; } } throw NotFound(name); } std::vector -LatticeSpaceVectorImpl::list_coords_exact(const Species& sp) const +LatticeSpaceVectorImpl::list_coords_exact(const Species &sp) const { std::vector retval; @@ -118,69 +105,58 @@ LatticeSpaceVectorImpl::list_coords_exact(const Species& sp) const return retval; } - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp((*itr).second); - for (MoleculePool::const_iterator itr(vp->begin()); itr != vp->end(); ++itr) + for (const auto &voxel : *vp) { - retval.push_back((*itr).coordinate); + retval.push_back(voxel.coordinate); } return retval; } std::vector -LatticeSpaceVectorImpl::list_coords(const Species& sp) const +LatticeSpaceVectorImpl::list_coords(const Species &sp) const { std::vector retval; - for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); - itr != molecule_pools_.end(); ++itr) + for (const auto &pool : molecule_pools_) { - if (!SpeciesExpressionMatcher(sp).match((*itr).first)) + if (!SpeciesExpressionMatcher(sp).match(pool.first)) { continue; } - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp(pool.second); - for (MoleculePool::const_iterator vitr(vp->begin()); - vitr != vp->end(); ++vitr) + for (const auto &voxel : *vp) { - retval.push_back((*vitr).coordinate); + retval.push_back(voxel.coordinate); } } return retval; } -std::vector > -LatticeSpaceVectorImpl::list_voxels() const +std::vector LatticeSpaceVectorImpl::list_voxels() const { - std::vector > retval; + std::vector retval; - for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); - itr != molecule_pools_.end(); ++itr) + for (const auto &pool : molecule_pools_) { - const boost::shared_ptr& vp((*itr).second); - - const std::string loc(get_location_serial(vp)); - const Species& sp(vp->species()); + const boost::shared_ptr &vp(pool.second); + const Species &sp(vp->species()); - for (MoleculePool::const_iterator i(vp->begin()); - i != vp->end(); ++i) + for (const auto &voxel : *vp) { - retval.push_back(std::make_pair( - (*i).pid, - ParticleVoxel(sp, (*i).coordinate, vp->radius(), vp->D(), loc))); + retval.push_back(VoxelView(voxel.pid, sp, voxel.coordinate)); } } - for (voxel_pool_map_type::const_iterator itr(voxel_pools_.begin()); - itr != voxel_pools_.end(); ++itr) + for (const auto &pool : voxel_pools_) { - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp(pool.second); + const Species &sp(vp->species()); - const std::string loc(get_location_serial(vp)); - const Species& sp(vp->species()); - - for (voxel_container::const_iterator i(voxels_.begin()); i != voxels_.end(); ++i) + for (voxel_container::const_iterator i(voxels_.begin()); + i != voxels_.end(); ++i) { if (*i != vp) { @@ -188,26 +164,24 @@ LatticeSpaceVectorImpl::list_voxels() const } const coordinate_type coord(std::distance(voxels_.begin(), i)); - retval.push_back(std::make_pair( - ParticleID(), - ParticleVoxel(sp, coord, vp->radius(), vp->D(), loc))); + retval.push_back(VoxelView(ParticleID(), sp, coord)); } } return retval; } -std::vector > -LatticeSpaceVectorImpl::list_voxels_exact(const Species& sp) const +std::vector +LatticeSpaceVectorImpl::list_voxels_exact(const Species &sp) const { - std::vector > retval; + std::vector retval; { voxel_pool_map_type::const_iterator itr(voxel_pools_.find(sp)); if (itr != voxel_pools_.end()) { - const boost::shared_ptr& vp((*itr).second); - const std::string loc(get_location_serial(vp)); - for (voxel_container::const_iterator i(voxels_.begin()); i != voxels_.end(); ++i) + const boost::shared_ptr &vp((*itr).second); + for (voxel_container::const_iterator i(voxels_.begin()); + i != voxels_.end(); ++i) { if (*i != vp) { @@ -215,9 +189,7 @@ LatticeSpaceVectorImpl::list_voxels_exact(const Species& sp) const } const coordinate_type coord(std::distance(voxels_.begin(), i)); - retval.push_back(std::make_pair( - ParticleID(), - ParticleVoxel(sp, coord, vp->radius(), vp->D(), loc))); + retval.push_back(VoxelView(ParticleID(), sp, coord)); } return retval; } @@ -227,14 +199,10 @@ LatticeSpaceVectorImpl::list_voxels_exact(const Species& sp) const molecule_pool_map_type::const_iterator itr(molecule_pools_.find(sp)); if (itr != molecule_pools_.end()) { - const boost::shared_ptr& vp((*itr).second); - const std::string loc(get_location_serial(vp)); - for (MoleculePool::const_iterator i(vp->begin()); - i != vp->end(); ++i) + const boost::shared_ptr &vp((*itr).second); + for (const auto &voxel : *vp) { - retval.push_back(std::make_pair( - (*i).pid, - ParticleVoxel(sp, (*i).coordinate, vp->radius(), vp->D(), loc))); + retval.push_back(VoxelView(voxel.pid, sp, voxel.coordinate)); } return retval; } @@ -242,23 +210,23 @@ LatticeSpaceVectorImpl::list_voxels_exact(const Species& sp) const return retval; // an empty vector } -std::vector > -LatticeSpaceVectorImpl::list_voxels(const Species& sp) const +std::vector +LatticeSpaceVectorImpl::list_voxels(const Species &sp) const { - std::vector > retval; + std::vector retval; SpeciesExpressionMatcher sexp(sp); - for (voxel_pool_map_type::const_iterator itr(voxel_pools_.begin()); - itr != voxel_pools_.end(); ++itr) + for (const auto &pool : voxel_pools_) { - if (!sexp.match((*itr).first)) + if (!sexp.match(pool.first)) { continue; } - const boost::shared_ptr& vp((*itr).second); - const std::string loc(get_location_serial(vp)); - for (voxel_container::const_iterator i(voxels_.begin()); i != voxels_.end(); ++i) + const boost::shared_ptr &vp(pool.second); + const Species &sp(vp->species()); + for (voxel_container::const_iterator i(voxels_.begin()); + i != voxels_.end(); ++i) { if (*i != vp) { @@ -266,28 +234,22 @@ LatticeSpaceVectorImpl::list_voxels(const Species& sp) const } const coordinate_type coord(std::distance(voxels_.begin(), i)); - retval.push_back(std::make_pair( - ParticleID(), - ParticleVoxel(sp, coord, vp->radius(), vp->D(), loc))); + retval.push_back(VoxelView(ParticleID(), sp, coord)); } } - for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); - itr != molecule_pools_.end(); ++itr) + for (const auto &pool : molecule_pools_) { - if (!sexp.match((*itr).first)) + if (!sexp.match(pool.first)) { continue; } - const boost::shared_ptr& vp((*itr).second); - const std::string loc(get_location_serial(vp)); - for (MoleculePool::const_iterator i(vp->begin()); - i != vp->end(); ++i) + const boost::shared_ptr &vp(pool.second); + const Species &sp(vp->species()); + for (const auto &voxel : *vp) { - retval.push_back(std::make_pair( - (*i).pid, - ParticleVoxel(sp, (*i).coordinate, vp->radius(), vp->D(), loc))); + retval.push_back(VoxelView(voxel.pid, sp, voxel.coordinate)); } } @@ -298,23 +260,20 @@ LatticeSpaceVectorImpl::list_voxels(const Species& sp) const * Protected functions */ -coordinate_type LatticeSpaceVectorImpl::get_coord( - const ParticleID& pid) const +coordinate_type LatticeSpaceVectorImpl::get_coord(const ParticleID &pid) const { - for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); - itr != molecule_pools_.end(); ++itr) + for (const auto &pool : molecule_pools_) { - const boost::shared_ptr& vp((*itr).second); - for (MoleculePool::const_iterator vitr(vp->begin()); - vitr != vp->end(); ++vitr) + const boost::shared_ptr &vp(pool.second); + for (const auto &voxel : *vp) { - if ((*vitr).pid == pid) + if (voxel.pid == pid) { - return (*vitr).coordinate; + return voxel.coordinate; } } } - return -1; //XXX: a bit dirty way + return -1; // XXX: a bit dirty way } // bool LatticeSpaceVectorImpl::has_species_exact(const Species& sp) const @@ -322,12 +281,11 @@ coordinate_type LatticeSpaceVectorImpl::get_coord( // return spmap_.find(sp) != spmap_.end(); // } -bool LatticeSpaceVectorImpl::remove_voxel(const ParticleID& pid) +bool LatticeSpaceVectorImpl::remove_voxel(const ParticleID &pid) { - for (molecule_pool_map_type::iterator i(molecule_pools_.begin()); - i != molecule_pools_.end(); ++i) + for (const auto &pool : molecule_pools_) { - const boost::shared_ptr& vp((*i).second); + const boost::shared_ptr &vp(pool.second); MoleculePool::const_iterator j(vp->find(pid)); if (j != vp->end()) { @@ -347,34 +305,31 @@ bool LatticeSpaceVectorImpl::remove_voxel(const ParticleID& pid) return false; } -bool LatticeSpaceVectorImpl::remove_voxel(const coordinate_type& coord) +bool LatticeSpaceVectorImpl::remove_voxel(const coordinate_type &coord) { boost::shared_ptr vp(voxels_.at(coord)); - if (vp->is_vacant()) + if (auto location_ptr = vp->location()) { - return false; - } - if (vp->remove_voxel_if_exists(coord)) - { - voxels_.at(coord) = vp->location(); - vp->location()->add_voxel( - coordinate_id_pair_type(ParticleID(), coord)); - return true; + if (vp->remove_voxel_if_exists(coord)) + { + voxels_.at(coord) = location_ptr; + location_ptr->add_voxel( + coordinate_id_pair_type(ParticleID(), coord)); + return true; + } } return false; } -bool -LatticeSpaceVectorImpl::move( - const coordinate_type& src, - const coordinate_type& dest, - const std::size_t candidate) +bool LatticeSpaceVectorImpl::move(const coordinate_type &src, + const coordinate_type &dest, + const std::size_t candidate) { return move_(src, dest, candidate).second; } -bool LatticeSpaceVectorImpl::can_move( - const coordinate_type& src, const coordinate_type& dest) const +bool LatticeSpaceVectorImpl::can_move(const coordinate_type &src, + const coordinate_type &dest) const { if (src == dest) return false; @@ -395,10 +350,8 @@ bool LatticeSpaceVectorImpl::can_move( } std::pair -LatticeSpaceVectorImpl::move_( - coordinate_type from, - coordinate_type to, - const std::size_t candidate) +LatticeSpaceVectorImpl::move_(coordinate_type from, coordinate_type to, + const std::size_t candidate) { if (from == to) { @@ -438,9 +391,7 @@ LatticeSpaceVectorImpl::move_( } std::pair -LatticeSpaceVectorImpl::move_( - coordinate_id_pair_type& info, - coordinate_type to) +LatticeSpaceVectorImpl::move_(coordinate_id_pair_type &info, coordinate_type to) { const coordinate_type from(info.coordinate); if (from == to) @@ -481,50 +432,39 @@ LatticeSpaceVectorImpl::move_( return std::pair(to, true); } -const Particle LatticeSpaceVectorImpl::particle_at( - const coordinate_type& coord) const -{ - boost::shared_ptr vp(voxels_.at(coord)); - - return Particle(vp->species(), - coordinate2position(coord), - vp->radius(), - vp->D()); -} - /* - * Change the Species and coordinate of a ParticleVoxel with ParticleID, pid, to - * v.species() and v.coordinate() respectively and return false. - * If no ParticleVoxel with pid is found, create a new ParticleVoxel at v.coordiante() and return ture. + * Change the Species and coordinate of a Voxel with ParticleID, pid, to + * species and coordinate respectively and return false. + * If no Voxel with pid is found, create a new Voxel at + * coordiante() and return true. */ -bool LatticeSpaceVectorImpl::update_voxel(const ParticleID& pid, ParticleVoxel v) +bool LatticeSpaceVectorImpl::update_voxel(const ParticleID &pid, + const Species &species, + const coordinate_type to_coord) { - const coordinate_type& to_coord(v.coordinate); if (!is_in_range(to_coord)) { throw NotSupported("Out of bounds"); } - boost::shared_ptr new_vp(get_voxel_pool(v)); //XXX: need MoleculeInfo + boost::shared_ptr new_vp( + find_voxel_pool(species)); // XXX: need MoleculeInfo boost::shared_ptr dest_vp(get_voxel_pool_at(to_coord)); if (dest_vp != new_vp->location()) { - throw NotSupported( - "Mismatch in the location. Failed to place '" - + new_vp->species().serial() + "' to '" - + dest_vp->species().serial() + "'."); + throw NotSupported("Mismatch in the location. Failed to place '" + + new_vp->species().serial() + "' to '" + + dest_vp->species().serial() + "'."); } - const coordinate_type - from_coord(pid != ParticleID() ? get_coord(pid) : -1); + const coordinate_type from_coord(pid != ParticleID() ? get_coord(pid) : -1); if (from_coord != -1) { // move - voxels_.at(from_coord) - ->remove_voxel_if_exists(from_coord); + voxels_.at(from_coord)->remove_voxel_if_exists(from_coord); - //XXX: use location? + // XXX: use location? dest_vp->replace_voxel(to_coord, from_coord); voxels_.at(from_coord) = dest_vp; @@ -541,11 +481,8 @@ bool LatticeSpaceVectorImpl::update_voxel(const ParticleID& pid, ParticleVoxel v return true; } -bool -LatticeSpaceVectorImpl::add_voxel( - const Species& sp, - const ParticleID& pid, - const coordinate_type& coordinate) +bool LatticeSpaceVectorImpl::add_voxel(const Species &sp, const ParticleID &pid, + const coordinate_type &coordinate) { boost::shared_ptr vpool(find_voxel_pool(sp)); boost::shared_ptr location(get_voxel_pool_at(coordinate)); @@ -560,10 +497,9 @@ LatticeSpaceVectorImpl::add_voxel( return true; } -bool -LatticeSpaceVectorImpl::add_voxels( - const Species& sp, - std::vector > voxels) +bool LatticeSpaceVectorImpl::add_voxels( + const Species &sp, + std::vector> voxels) { // this function doesn't check location. boost::shared_ptr mtb; @@ -576,11 +512,10 @@ LatticeSpaceVectorImpl::add_voxels( return false; } - for (std::vector >::iterator itr(voxels.begin()); - itr != voxels.end(); ++itr) + for (const auto &voxel : voxels) { - const ParticleID pid((*itr).first); - const coordinate_type coord((*itr).second); + const ParticleID pid(voxel.first); + const coordinate_type coord(voxel.second); get_voxel_pool_at(coord)->remove_voxel_if_exists(coord); mtb->add_voxel(coordinate_id_pair_type(pid, coord)); voxels_.at(coord) = mtb; @@ -588,4 +523,4 @@ LatticeSpaceVectorImpl::add_voxels( return true; } -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/core/LatticeSpaceVectorImpl.hpp b/ecell4/core/LatticeSpaceVectorImpl.hpp index 506c2ad47..b6b26cd0b 100644 --- a/ecell4/core/LatticeSpaceVectorImpl.hpp +++ b/ecell4/core/LatticeSpaceVectorImpl.hpp @@ -3,20 +3,17 @@ #include "HCPLatticeSpace.hpp" -namespace ecell4 { +namespace ecell4 +{ -class LatticeSpaceVectorImpl - : public HCPLatticeSpace +class LatticeSpaceVectorImpl : public HCPLatticeSpace { public: - typedef HCPLatticeSpace base_type; - typedef std::vector > voxel_container; + typedef std::vector> voxel_container; public: - - LatticeSpaceVectorImpl(const Real3& edge_lengths, - const Real& voxel_radius, + LatticeSpaceVectorImpl(const Real3 &edge_lengths, const Real &voxel_radius, const bool is_periodic = true); ~LatticeSpaceVectorImpl(); @@ -28,44 +25,45 @@ class LatticeSpaceVectorImpl Integer num_species() const; - bool remove_voxel(const ParticleID& pid); - bool remove_voxel(const coordinate_type& coord); + bool remove_voxel(const ParticleID &pid); + bool remove_voxel(const coordinate_type &coord); - bool update_structure(const Particle& p); + bool update_structure(const Particle &p); /* * for Simulator * * using Species and coordinate_type */ - std::vector > list_voxels() const; - std::vector > list_voxels(const Species& sp) const; - std::vector > list_voxels_exact(const Species& sp) const; + std::vector list_voxels() const; + std::vector list_voxels(const Species &sp) const; + std::vector list_voxels_exact(const Species &sp) const; - std::pair get_voxel_at(const coordinate_type& coord) const; + bool update_voxel(const ParticleID &pid, const Species &species, + const coordinate_type coordinate); + bool add_voxel(const Species &species, const ParticleID &pid, + const coordinate_type &coord); - bool update_voxel(const ParticleID& pid, ParticleVoxel v); - bool add_voxel(const Species& species, const ParticleID& pid, const coordinate_type& coord); + bool add_voxels(const Species &species, + std::vector> voxels); - bool add_voxels(const Species& species, - std::vector > voxels); + const Species &find_species(std::string name) const; + std::vector list_coords(const Species &sp) const; + std::vector list_coords_exact(const Species &sp) const; - const Species& find_species(std::string name) const; - std::vector list_coords(const Species& sp) const; - std::vector list_coords_exact(const Species& sp) const; - - boost::shared_ptr get_voxel_pool_at(const coordinate_type& coord) const + boost::shared_ptr + get_voxel_pool_at(const coordinate_type &coord) const { return voxels_.at(coord); } - bool move(const coordinate_type& src, - const coordinate_type& dest, - const std::size_t candidate=0); - bool can_move(const coordinate_type& src, const coordinate_type& dest) const; + bool move(const coordinate_type &src, const coordinate_type &dest, + const std::size_t candidate = 0); + bool can_move(const coordinate_type &src, + const coordinate_type &dest) const; - coordinate_type - get_neighbor(const coordinate_type& coord, const Integer& nrand) const + coordinate_type get_neighbor(const coordinate_type &coord, + const Integer &nrand) const { coordinate_type const dest = get_neighbor_(coord, nrand); @@ -79,27 +77,22 @@ class LatticeSpaceVectorImpl } } - bool is_periodic() const - { - return is_periodic_; - } + bool is_periodic() const { return is_periodic_; } #ifdef WITH_HDF5 /* * HDF5 Save */ - void save_hdf5(H5::Group* root) const + void save_hdf5(H5::Group *root) const { save_lattice_space(*this, root, "LatticeSpaceVectorImpl"); } - void load_hdf5(const H5::Group& root) - { - load_lattice_space(root, this); - } + void load_hdf5(const H5::Group &root) { load_lattice_space(root, this); } #endif - void reset(const Real3& edge_lengths, const Real& voxel_radius, const bool is_periodic) + void reset(const Real3 &edge_lengths, const Real &voxel_radius, + const bool is_periodic) { base_type::reset(edge_lengths, voxel_radius, is_periodic); @@ -107,30 +100,24 @@ class LatticeSpaceVectorImpl initialize_voxels(is_periodic_); } - const Particle particle_at(const coordinate_type& coord) const; - protected: - - coordinate_type apply_boundary_(const coordinate_type& coord) const + coordinate_type apply_boundary_(const coordinate_type &coord) const { return periodic_transpose(coord); } void initialize_voxels(const bool is_periodic); - std::pair - move_(coordinate_type from, - coordinate_type to, - const std::size_t candidate=0); + std::pair move_(coordinate_type from, + coordinate_type to, + const std::size_t candidate = 0); - std::pair - move_(coordinate_id_pair_type& info, - coordinate_type to); + std::pair move_(coordinate_id_pair_type &info, + coordinate_type to); - coordinate_type get_coord(const ParticleID& pid) const; + coordinate_type get_coord(const ParticleID &pid) const; protected: - bool is_periodic_; voxel_container voxels_; @@ -139,6 +126,6 @@ class LatticeSpaceVectorImpl boost::shared_ptr periodic_; }; -} // ecell4 +} // namespace ecell4 #endif diff --git a/ecell4/core/MoleculePool.hpp b/ecell4/core/MoleculePool.hpp index 038cbcba0..bec416382 100644 --- a/ecell4/core/MoleculePool.hpp +++ b/ecell4/core/MoleculePool.hpp @@ -3,13 +3,12 @@ #include "VoxelPool.hpp" -namespace ecell4 { +namespace ecell4 +{ -class MoleculePool - : public VoxelPool +class MoleculePool : public VoxelPool { public: - typedef VoxelPool base_type; typedef std::vector container_type; @@ -17,35 +16,25 @@ class MoleculePool typedef container_type::iterator iterator; public: - - MoleculePool( - const Species& species, boost::weak_ptr location, - const Real& radius=0.0, const Real& D=0.0) - : base_type(species, location, radius, D) + MoleculePool(const Species &species, boost::weak_ptr location) + : base_type(species, location) { ; } - virtual ~MoleculePool() - { - ; - } + virtual ~MoleculePool() { ; } - virtual voxel_type_type const voxel_type() const - { - return DEFAULT; - } + virtual voxel_type_type const voxel_type() const { return DEFAULT; } public: - - virtual void add_voxel(const coordinate_id_pair_type& info) + virtual void add_voxel(const coordinate_id_pair_type &info) { voxels_.push_back(info); } - virtual void replace_voxel( - const coordinate_type& from_coord, const coordinate_type& to_coord, - const std::size_t candidate = 0) + virtual void replace_voxel(const coordinate_type &from_coord, + const coordinate_type &to_coord, + const std::size_t candidate = 0) { container_type::iterator itr(find(from_coord, candidate)); if (itr == voxels_.end()) @@ -57,7 +46,7 @@ class MoleculePool (*itr).coordinate = to_coord; } - virtual bool remove_voxel_if_exists(const coordinate_type& coord) + virtual bool remove_voxel_if_exists(const coordinate_type &coord) { container_type::iterator itr(find(coord)); if (itr != voxels_.end()) @@ -68,7 +57,7 @@ class MoleculePool return false; } - virtual const ParticleID get_particle_id(const coordinate_type& coord) const + virtual const ParticleID get_particle_id(const coordinate_type &coord) const { container_type::const_iterator i(this->find(coord)); if (i == voxels_.end()) @@ -79,15 +68,14 @@ class MoleculePool } public: - - void remove_voxel(const container_type::iterator& position) + void remove_voxel(const container_type::iterator &position) { // voxels_.erase(position); (*position) = voxels_.back(); voxels_.pop_back(); } - coordinate_id_pair_type pop(const coordinate_type& coord) + coordinate_id_pair_type pop(const coordinate_type &coord) { container_type::iterator position(this->find(coord)); const coordinate_id_pair_type info(*position); @@ -95,8 +83,8 @@ class MoleculePool return info; } - void replace_voxel( - const coordinate_type& from_coord, const coordinate_id_pair_type& to_info) + void replace_voxel(const coordinate_type &from_coord, + const coordinate_id_pair_type &to_info) { container_type::iterator itr(find(from_coord)); if (itr == voxels_.end()) @@ -107,7 +95,8 @@ class MoleculePool (*itr) = to_info; } - void swap(const container_type::iterator& a, const container_type::iterator& b) + void swap(const container_type::iterator &a, + const container_type::iterator &b) { if (a == b) { @@ -119,57 +108,36 @@ class MoleculePool (*a) = info; } - coordinate_id_pair_type& at(const Integer& index) + coordinate_id_pair_type &at(const Integer &index) { return voxels_.at(index); } - coordinate_id_pair_type const& at(const Integer& index) const + coordinate_id_pair_type const &at(const Integer &index) const { return voxels_.at(index); } - coordinate_id_pair_type& operator[](const Integer& n) - { - return voxels_[n]; - } + coordinate_id_pair_type &operator[](const Integer &n) { return voxels_[n]; } - coordinate_id_pair_type const& operator[](const Integer& n) const + coordinate_id_pair_type const &operator[](const Integer &n) const { return voxels_[n]; } - const Integer size() const - { - return voxels_.size(); - } + const Integer size() const { return voxels_.size(); } - void shuffle(RandomNumberGenerator& rng) - { - ecell4::shuffle(rng, voxels_); - } + void shuffle(RandomNumberGenerator &rng) { ecell4::shuffle(rng, voxels_); } - container_type::iterator begin() - { - return voxels_.begin(); - } + container_type::iterator begin() { return voxels_.begin(); } - container_type::const_iterator begin() const - { - return voxels_.begin(); - } + container_type::const_iterator begin() const { return voxels_.begin(); } - container_type::iterator end() - { - return voxels_.end(); - } + container_type::iterator end() { return voxels_.end(); } - container_type::const_iterator end() const - { - return voxels_.end(); - } + container_type::const_iterator end() const { return voxels_.end(); } - container_type::iterator find(const ParticleID& pid) + container_type::iterator find(const ParticleID &pid) { container_type::iterator itr; for (itr = voxels_.begin(); itr != voxels_.end(); ++itr) @@ -182,7 +150,7 @@ class MoleculePool return itr; } - container_type::const_iterator find(const ParticleID& pid) const + container_type::const_iterator find(const ParticleID &pid) const { container_type::const_iterator itr; for (itr = voxels_.begin(); itr != voxels_.end(); ++itr) @@ -196,9 +164,8 @@ class MoleculePool } protected: - - container_type::iterator find( - coordinate_type coord, const std::size_t candidate = 0) + container_type::iterator find(coordinate_type coord, + const std::size_t candidate = 0) { container_type::iterator itr; if (candidate < voxels_.size()) @@ -217,8 +184,8 @@ class MoleculePool return itr; } - container_type::const_iterator find( - coordinate_type coord, const std::size_t candidate = 0) const + container_type::const_iterator find(coordinate_type coord, + const std::size_t candidate = 0) const { container_type::const_iterator itr; if (candidate < voxels_.size()) @@ -238,10 +205,9 @@ class MoleculePool } protected: - container_type voxels_; }; -} // ecell4 +} // namespace ecell4 #endif diff --git a/ecell4/core/OffLatticeSpace.cpp b/ecell4/core/OffLatticeSpace.cpp index a4fc63926..7c54001ed 100644 --- a/ecell4/core/OffLatticeSpace.cpp +++ b/ecell4/core/OffLatticeSpace.cpp @@ -1,33 +1,35 @@ -#include #include "Context.hpp" -#include "VacantType.hpp" #include "MoleculePool.hpp" #include "OffLatticeSpace.hpp" +#include "VacantType.hpp" +#include + +namespace ecell4 +{ + +OffLatticeSpace::OffLatticeSpace(const Real &voxel_radius, + const Species &species) + : base_type(voxel_radius), voxels_(), positions_(), adjoinings_() +{ + vacant_ = boost::shared_ptr( + new StructureType(species, boost::weak_ptr())); +} -namespace ecell4 { - -OffLatticeSpace::OffLatticeSpace(const Real& voxel_radius) - : base_type(voxel_radius), - voxels_(), - positions_(), - adjoinings_() -{} - -OffLatticeSpace::OffLatticeSpace(const Real& voxel_radius, - const position_container& positions, - const coordinate_pair_list_type& adjoining_pairs) - : base_type(voxel_radius), - voxels_(), - positions_(), - adjoinings_() +OffLatticeSpace::OffLatticeSpace( + const Real &voxel_radius, const Species &species, + const position_container &positions, + const coordinate_pair_list_type &adjoining_pairs) + : base_type(voxel_radius), voxels_(), positions_(), adjoinings_() { + vacant_ = boost::shared_ptr( + new StructureType(species, boost::weak_ptr())); reset(positions, adjoining_pairs); } OffLatticeSpace::~OffLatticeSpace() {} -void OffLatticeSpace::reset(const position_container& positions, - const coordinate_pair_list_type& adjoining_pairs) +void OffLatticeSpace::reset(const position_container &positions, + const coordinate_pair_list_type &adjoining_pairs) { voxels_.clear(); positions_.clear(); @@ -65,7 +67,7 @@ void OffLatticeSpace::reset(const position_container& positions, } boost::optional -OffLatticeSpace::get_coord(const ParticleID& pid) const +OffLatticeSpace::get_coord(const ParticleID &pid) const { if (pid == ParticleID()) return boost::none; @@ -73,9 +75,9 @@ OffLatticeSpace::get_coord(const ParticleID& pid) const for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); itr != molecule_pools_.end(); ++itr) { - const boost::shared_ptr& vp((*itr).second); - for (MoleculePool::const_iterator vitr(vp->begin()); - vitr != vp->end(); ++vitr) + const boost::shared_ptr &vp((*itr).second); + for (MoleculePool::const_iterator vitr(vp->begin()); vitr != vp->end(); + ++vitr) { if ((*vitr).pid == pid) { @@ -87,59 +89,34 @@ OffLatticeSpace::get_coord(const ParticleID& pid) const return boost::none; } - /* * public functions */ // Same as LatticeSpaceVectorImpl -std::pair -OffLatticeSpace::get_voxel_at(const coordinate_type& coord) const -{ - boost::shared_ptr vp(voxels_.at(coord)); - return std::make_pair(vp->get_particle_id(coord), - ParticleVoxel(vp->species(), - coord, - vp->radius(), - vp->D(), - get_location_serial(vp))); -} - -// Same as LatticeSpaceVectorImpl -const Particle OffLatticeSpace::particle_at(const coordinate_type& coord) const +bool OffLatticeSpace::update_voxel(const ParticleID &pid, + const Species &species, + const coordinate_type to_coord) { - boost::shared_ptr vp(voxels_.at(coord)); - return Particle( - vp->species(), - coordinate2position(coord), - vp->radius(), vp->D()); -} - -// Same as LatticeSpaceVectorImpl -bool OffLatticeSpace::update_voxel(const ParticleID& pid, ParticleVoxel v) -{ - const coordinate_type& to_coord(v.coordinate); if (!is_in_range(to_coord)) throw NotSupported("Out of bounds"); - boost::shared_ptr new_vp(get_voxel_pool(v)); + boost::shared_ptr new_vp(find_voxel_pool(species)); boost::shared_ptr dest_vp(get_voxel_pool_at(to_coord)); if (dest_vp != new_vp->location()) { - throw NotSupported( - "Mismatch in the location. Failed to place '" - + new_vp->species().serial() + "' to '" - + dest_vp->species().serial() + "'."); + throw NotSupported("Mismatch in the location. Failed to place '" + + new_vp->species().serial() + "' to '" + + dest_vp->species().serial() + "'."); } if (boost::optional from_coord = get_coord(pid)) { // move - voxels_.at(*from_coord) - ->remove_voxel_if_exists(*from_coord); + voxels_.at(*from_coord)->remove_voxel_if_exists(*from_coord); - //XXX: use location? + // XXX: use location? dest_vp->replace_voxel(to_coord, *from_coord); voxels_.at(*from_coord) = dest_vp; @@ -158,8 +135,8 @@ bool OffLatticeSpace::update_voxel(const ParticleID& pid, ParticleVoxel v) return true; } -bool OffLatticeSpace::add_voxel( - const Species& species, const ParticleID& pid, const coordinate_type& coord) +bool OffLatticeSpace::add_voxel(const Species &species, const ParticleID &pid, + const coordinate_type &coord) { boost::shared_ptr vpool(find_voxel_pool(species)); boost::shared_ptr location(get_voxel_pool_at(coord)); @@ -175,12 +152,12 @@ bool OffLatticeSpace::add_voxel( } // Same as LatticeSpaceVectorImpl -bool OffLatticeSpace::remove_voxel(const ParticleID& pid) +bool OffLatticeSpace::remove_voxel(const ParticleID &pid) { for (molecule_pool_map_type::iterator i(molecule_pools_.begin()); i != molecule_pools_.end(); ++i) { - const boost::shared_ptr& vp((*i).second); + const boost::shared_ptr &vp((*i).second); MoleculePool::const_iterator j(vp->find(pid)); if (j != vp->end()) { @@ -201,45 +178,51 @@ bool OffLatticeSpace::remove_voxel(const ParticleID& pid) } // Same as LatticeSpaceVectorImpl -bool OffLatticeSpace::remove_voxel(const coordinate_type& coord) +bool OffLatticeSpace::remove_voxel(const coordinate_type &coord) { boost::shared_ptr vp(voxels_.at(coord)); - if (vp->is_vacant()) - { - return false; - } - if (vp->remove_voxel_if_exists(coord)) + if (auto location_ptr = vp->location()) { - voxels_.at(coord) = vp->location(); - vp->location()->add_voxel( - coordinate_id_pair_type(ParticleID(), coord)); - return true; + if (vp->remove_voxel_if_exists(coord)) + { + voxels_.at(coord) = location_ptr; + location_ptr->add_voxel( + coordinate_id_pair_type(ParticleID(), coord)); + return true; + } } return false; } -bool OffLatticeSpace::can_move(const coordinate_type& src, const coordinate_type& dest) const +bool OffLatticeSpace::can_move(const coordinate_type &src, + const coordinate_type &dest) const { - if (src == dest) return false; + if (src == dest) + return false; boost::shared_ptr src_vp(voxels_.at(src)); - if (src_vp->is_vacant()) return false; + if (src_vp->is_vacant()) + return false; boost::shared_ptr dest_vp(voxels_.at(dest)); return (voxels_.at(dest) == src_vp->location()); } -bool OffLatticeSpace::move(const coordinate_type& src, const coordinate_type& dest, - const std::size_t candidate) +bool OffLatticeSpace::move(const coordinate_type &src, + const coordinate_type &dest, + const std::size_t candidate) { - if (src == dest) return false; + if (src == dest) + return false; boost::shared_ptr src_vp(voxels_.at(src)); - if (src_vp->is_vacant()) return true; + if (src_vp->is_vacant()) + return true; boost::shared_ptr dest_vp(voxels_.at(dest)); - if (dest_vp != src_vp->location()) return false; + if (dest_vp != src_vp->location()) + return false; src_vp->replace_voxel(src, dest, candidate); voxels_.at(src) = dest_vp; @@ -251,7 +234,7 @@ bool OffLatticeSpace::move(const coordinate_type& src, const coordinate_type& de } OffLatticeSpace::coordinate_type -OffLatticeSpace::position2coordinate(const Real3& pos) const +OffLatticeSpace::position2coordinate(const Real3 &pos) const { coordinate_type coordinate(0); Real shortest_length = length(positions_.at(0) - pos); @@ -269,4 +252,4 @@ OffLatticeSpace::position2coordinate(const Real3& pos) const return coordinate; } -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/core/OffLatticeSpace.hpp b/ecell4/core/OffLatticeSpace.hpp index df8b5ba7a..55ed5634a 100644 --- a/ecell4/core/OffLatticeSpace.hpp +++ b/ecell4/core/OffLatticeSpace.hpp @@ -1,8 +1,8 @@ #ifndef ECELL4_OFFLATTICE_SPACE_HPP #define ECELL4_OFFLATTICE_SPACE_HPP -#include #include "VoxelSpaceBase.hpp" +#include namespace ecell4 { @@ -10,10 +10,9 @@ namespace ecell4 class OffLatticeSpace : public VoxelSpaceBase { protected: - typedef VoxelSpaceBase base_type; - typedef std::vector > voxel_container; - typedef std::vector > adjoining_container; + typedef std::vector> voxel_container; + typedef std::vector> adjoining_container; public: typedef std::pair coordinate_pair_type; @@ -23,22 +22,22 @@ class OffLatticeSpace : public VoxelSpaceBase /* * Constructor and Destructor */ - OffLatticeSpace(const Real& voxel_radius); - OffLatticeSpace(const Real& voxel_radius, - const position_container& positions, - const coordinate_pair_list_type& adjoining_pairs); + OffLatticeSpace(const Real &voxel_radius, const Species &species); + OffLatticeSpace(const Real &voxel_radius, const Species &species, + const position_container &positions, + const coordinate_pair_list_type &adjoining_pairs); ~OffLatticeSpace(); /* * Space Traits */ #ifdef WITH_HDF5 - void save_hdf5(H5::Group* root) const + void save_hdf5(H5::Group *root) const { throw NotSupported("OffLatticeSpace::save_hdf5 is not supported."); } - void load_hdf5(const H5::Group& root) + void load_hdf5(const H5::Group &root) { throw NotSupported("OffLatticeSpace::load_hdf5 is not supported."); } @@ -47,24 +46,19 @@ class OffLatticeSpace : public VoxelSpaceBase /* * ParticleSpace Traits */ - const Real3& edge_lengths() const - { - return edge_lengths_; - } + const Real3 &edge_lengths() const { return edge_lengths_; } // tmp - void set_lengths(const Real3& edge_lengths) + void set_lengths(const Real3 &edge_lengths) { edge_lengths_ = edge_lengths; } - const Particle particle_at(const coordinate_type& coord) const; - /* * VoxelSpace Traits */ - std::pair get_voxel_at(const coordinate_type& coord) const; - boost::shared_ptr get_voxel_pool_at(const coordinate_type& coord) const + boost::shared_ptr + get_voxel_pool_at(const coordinate_type &coord) const { return voxels_.at(coord); } @@ -72,78 +66,70 @@ class OffLatticeSpace : public VoxelSpaceBase /* * Coordinate Transformation */ - Real3 coordinate2position(const coordinate_type& coord) const + Real3 coordinate2position(const coordinate_type &coord) const { return positions_.at(coord); } - coordinate_type position2coordinate(const Real3& pos) const; + coordinate_type position2coordinate(const Real3 &pos) const; /* * Neighbor */ - Integer num_neighbors(const coordinate_type& coord) const + Integer num_neighbors(const coordinate_type &coord) const { return adjoinings_.at(coord).size(); } - coordinate_type - get_neighbor(const coordinate_type& coord, const Integer& nrand) const + coordinate_type get_neighbor(const coordinate_type &coord, + const Integer &nrand) const { return adjoinings_.at(coord).at(nrand); } /* - * ParticleVoxel Manipulation + * Voxel Manipulation */ - bool update_voxel(const ParticleID& pid, ParticleVoxel v); - bool add_voxel(const Species& species, const ParticleID& pid, const coordinate_type& coord); - bool remove_voxel(const ParticleID& pid); - bool remove_voxel(const coordinate_type& coord); + bool update_voxel(const ParticleID &pid, const Species &species, + const coordinate_type coordinate); + bool add_voxel(const Species &species, const ParticleID &pid, + const coordinate_type &coord); + bool remove_voxel(const ParticleID &pid); + bool remove_voxel(const coordinate_type &coord); - bool can_move(const coordinate_type& src, - const coordinate_type& dest) const; + bool can_move(const coordinate_type &src, + const coordinate_type &dest) const; - bool move(const coordinate_type& src, - const coordinate_type& dest, - const std::size_t candidate=0); + bool move(const coordinate_type &src, const coordinate_type &dest, + const std::size_t candidate = 0); - Integer size() const - { - return voxels_.size(); - } + Integer size() const { return voxels_.size(); } Integer3 shape() const { throw NotSupported("OffLatticeSpace::shape() is not supported."); } - Integer actual_size() const - { - return size(); - } + Integer actual_size() const { return size(); } protected: - - bool is_in_range(const coordinate_type& coord) const + bool is_in_range(const coordinate_type &coord) const { return 0 <= coord && coord < static_cast(voxels_.size()); } - void reset(const position_container& positions, - const coordinate_pair_list_type& adjoining_pairs); - boost::optional get_coord(const ParticleID& pid) const; + void reset(const position_container &positions, + const coordinate_pair_list_type &adjoining_pairs); + boost::optional get_coord(const ParticleID &pid) const; protected: - voxel_container voxels_; position_container positions_; adjoining_container adjoinings_; Real3 edge_lengths_; - }; -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_OFFLATTICE_SPACE_HPP */ diff --git a/ecell4/core/ParticleVoxel.hpp b/ecell4/core/ParticleVoxel.hpp deleted file mode 100644 index 8db435dc4..000000000 --- a/ecell4/core/ParticleVoxel.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef ECELL4_VOXEL_HPP -#define ECELL4_VOXEL_HPP - -#include "Species.hpp" -#include "types.hpp" - -namespace ecell4 -{ - -struct ParticleVoxel -{ - typedef Integer coordinate_type; - - ParticleVoxel() - { - ; - } - - ParticleVoxel(const Species& sp, - const coordinate_type& coord, - const Real& radius, - const Real& D, - const std::string& loc = "") - : species(sp), coordinate(coord), radius(radius), D(D), loc(loc) - {} - - Species species; - coordinate_type coordinate; - Real radius; - Real D; - std::string loc; -}; - -} - -#endif diff --git a/ecell4/core/StructureType.hpp b/ecell4/core/StructureType.hpp index c4ac77e83..913cd1745 100644 --- a/ecell4/core/StructureType.hpp +++ b/ecell4/core/StructureType.hpp @@ -3,44 +3,28 @@ #include "VoxelPool.hpp" - namespace ecell4 { -class StructureType - : public VoxelPool +class StructureType : public VoxelPool { private: - typedef VoxelPool base_type; public: - - StructureType( - const Species& species, boost::weak_ptr location, - const Real& radius = 0.0) - : base_type(species, location, radius, 0), - size_(0) + StructureType(const Species &species, boost::weak_ptr location) + : base_type(species, location), size_(0) { ; } - virtual ~StructureType() - { - ; - } + virtual ~StructureType() { ; } - virtual voxel_type_type const voxel_type() const - { - return STRUCTURE; - } + virtual voxel_type_type const voxel_type() const { return STRUCTURE; } - const Integer size() const - { - return size_; - } + const Integer size() const { return size_; } - void add_voxel(const coordinate_id_pair_type& info) + void add_voxel(const coordinate_id_pair_type &info) { if (info.pid != ParticleID()) { @@ -50,24 +34,22 @@ class StructureType ++size_; } - coordinate_id_pair_type pop(const coordinate_type& coord) + coordinate_id_pair_type pop(const coordinate_type &coord) { --size_; return coordinate_id_pair_type(ParticleID(), coord); } - bool remove_voxel_if_exists(const coordinate_type& coord) + bool remove_voxel_if_exists(const coordinate_type &coord) { --size_; return true; } private: - Integer size_; - }; -} //ecell4 +} // namespace ecell4 #endif /* ECELL4_STRUCTURE_TYPE_HPP */ diff --git a/ecell4/core/SubvolumeSpaceHDF5Writer.hpp b/ecell4/core/SubvolumeSpaceHDF5Writer.hpp index 490e4438f..ceae9cff1 100644 --- a/ecell4/core/SubvolumeSpaceHDF5Writer.hpp +++ b/ecell4/core/SubvolumeSpaceHDF5Writer.hpp @@ -1,30 +1,29 @@ #ifndef ECELL4_SUBVOLUME_SPACE_HDF5_WRITER_HPP #define ECELL4_SUBVOLUME_SPACE_HDF5_WRITER_HPP +#include +#include +#include +#include #include #include #include -#include -#include -#include -#include -#include #include +#include -#include "types.hpp" #include "Species.hpp" -#include "ParticleVoxel.hpp" - -#include "Space.hpp" // just for Space::space_kind +#include "types.hpp" +#include "Space.hpp" // just for Space::space_kind namespace ecell4 { struct SubvolumeSpaceHDF5Traits { - typedef struct h5_species_struct { + typedef struct h5_species_struct + { uint32_t id; char serial[32]; // species' serial may exceed the limit double D; @@ -34,9 +33,9 @@ struct SubvolumeSpaceHDF5Traits static H5::CompType get_species_comp_type() { H5::CompType h5_species_comp_type(sizeof(h5_species_struct)); -#define INSERT_MEMBER(member, type) \ - H5Tinsert(h5_species_comp_type.getId(), #member,\ - HOFFSET(h5_species_struct, member), type.getId()) +#define INSERT_MEMBER(member, type) \ + H5Tinsert(h5_species_comp_type.getId(), #member, \ + HOFFSET(h5_species_struct, member), type.getId()) INSERT_MEMBER(id, H5::PredType::STD_I32LE); INSERT_MEMBER(serial, H5::StrType(H5::PredType::C_S1, 32)); INSERT_MEMBER(D, H5::PredType::NATIVE_DOUBLE); @@ -57,7 +56,8 @@ struct SubvolumeSpaceHDF5Traits return h5_species_comp_type; } - typedef struct h5_structures_struct { + typedef struct h5_structures_struct + { uint32_t id; char serial[32]; // structures' serial may exceed the limit // uint32_t dimension; @@ -66,9 +66,9 @@ struct SubvolumeSpaceHDF5Traits static H5::CompType get_structures_comp_type() { H5::CompType h5_structures_comp_type(sizeof(h5_structures_struct)); -#define INSERT_MEMBER(member, type) \ - H5Tinsert(h5_structures_comp_type.getId(), #member,\ - HOFFSET(h5_structures_struct, member), type.getId()) +#define INSERT_MEMBER(member, type) \ + H5Tinsert(h5_structures_comp_type.getId(), #member, \ + HOFFSET(h5_structures_struct, member), type.getId()) INSERT_MEMBER(id, H5::PredType::STD_I32LE); INSERT_MEMBER(serial, H5::StrType(H5::PredType::C_S1, 32)); // INSERT_MEMBER(dimension, H5::PredType::STD_I32LE); @@ -80,37 +80,35 @@ struct SubvolumeSpaceHDF5Traits // std::string("serial"), HOFFSET(h5_structures_struct, serial), // H5::StrType(H5::PredType::C_S1, 32)); // // h5_species_comp_type.insertMember( - // // std::string("dimension"), HOFFSET(h5_structure_struct, dimension), + // // std::string("dimension"), HOFFSET(h5_structure_struct, + // dimension), // // H5::PredType::STD_I32LE); return h5_structures_comp_type; } }; -template -void save_subvolume_space(const Tspace_& space, H5::Group* root) +template +void save_subvolume_space(const Tspace_ &space, H5::Group *root) { typedef SubvolumeSpaceHDF5Traits traits_type; typedef typename traits_type::h5_species_struct h5_species_struct; // typedef typename traits_type::h5_voxel_struct h5_voxel_struct; typedef typename traits_type::h5_structures_struct h5_structures_struct; - // typedef std::vector > - // voxel_container_type; - const unsigned int num_subvolumes(space.num_subvolumes()); const std::vector species(space.list_species()); - boost::multi_array - h5_num_table(boost::extents[species.size()][num_subvolumes]); - boost::scoped_array - h5_species_table(new h5_species_struct[species.size()]); + boost::multi_array h5_num_table( + boost::extents[species.size()][num_subvolumes]); + boost::scoped_array h5_species_table( + new h5_species_struct[species.size()]); for (unsigned int i(0); i < species.size(); ++i) { const unsigned int sid(i + 1); h5_species_table[i].id = sid; std::strcpy(h5_species_table[i].serial, species[i].serial().c_str()); - const boost::shared_ptr& - pool = space.get_pool(species[i]); + const boost::shared_ptr &pool = + space.get_pool(species[i]); h5_species_table[i].D = pool->D(); std::strcpy(h5_species_table[i].loc, pool->loc().c_str()); @@ -121,16 +119,17 @@ void save_subvolume_space(const Tspace_& space, H5::Group* root) } const std::vector structures(space.list_structures()); - boost::multi_array - h5_stcoordinate_table(boost::extents[structures.size()][num_subvolumes]); - boost::scoped_array - h5_structures_table(new h5_structures_struct[structures.size()]); + boost::multi_array h5_stcoordinate_table( + boost::extents[structures.size()][num_subvolumes]); + boost::scoped_array h5_structures_table( + new h5_structures_struct[structures.size()]); for (unsigned int i(0); i < structures.size(); ++i) { const unsigned int sid(i + 1); h5_structures_table[i].id = sid; std::strcpy(h5_structures_table[i].serial, structures[i].c_str()); - // h5_structures_table[i].dimension = space.get_dimension(structures[i]); + // h5_structures_table[i].dimension = + // space.get_dimension(structures[i]); for (unsigned int j(0); j < num_subvolumes; ++j) { // const bool exist = space.check_structure(structures[i], j); @@ -144,27 +143,23 @@ void save_subvolume_space(const Tspace_& space, H5::Group* root) hsize_t dim1[] = {species.size(), num_subvolumes}; H5::DataSpace dataspace1(RANK1, dim1); - boost::scoped_ptr dataset1(new H5::DataSet( - root->createDataSet( - "num_molecules", H5::PredType::STD_I64LE, dataspace1))); + boost::scoped_ptr dataset1(new H5::DataSet(root->createDataSet( + "num_molecules", H5::PredType::STD_I64LE, dataspace1))); hsize_t dim2[] = {species.size()}; H5::DataSpace dataspace2(RANK2, dim2); - boost::scoped_ptr dataset2(new H5::DataSet( - root->createDataSet( - "species", traits_type::get_species_comp_type(), dataspace2))); + boost::scoped_ptr dataset2(new H5::DataSet(root->createDataSet( + "species", traits_type::get_species_comp_type(), dataspace2))); hsize_t dim3[] = {structures.size(), num_subvolumes}; H5::DataSpace dataspace3(RANK1, dim3); - boost::scoped_ptr dataset3(new H5::DataSet( - root->createDataSet( - "stcoordinates", H5::PredType::IEEE_F64LE, dataspace3))); + boost::scoped_ptr dataset3(new H5::DataSet(root->createDataSet( + "stcoordinates", H5::PredType::IEEE_F64LE, dataspace3))); hsize_t dim4[] = {structures.size()}; H5::DataSpace dataspace4(RANK2, dim4); - boost::scoped_ptr dataset4(new H5::DataSet( - root->createDataSet( - "structures", traits_type::get_structures_comp_type(), dataspace4))); + boost::scoped_ptr dataset4(new H5::DataSet(root->createDataSet( + "structures", traits_type::get_structures_comp_type(), dataspace4))); dataset1->write(h5_num_table.data(), dataset1->getDataType()); dataset2->write(h5_species_table.get(), dataset2->getDataType()); @@ -172,37 +167,33 @@ void save_subvolume_space(const Tspace_& space, H5::Group* root) dataset4->write(h5_structures_table.get(), dataset4->getDataType()); const uint32_t space_type = static_cast(Space::SUBVOLUME); - H5::Attribute attr_space_type( - root->createAttribute( - "type", H5::PredType::STD_I32LE, H5::DataSpace(H5S_SCALAR))); + H5::Attribute attr_space_type(root->createAttribute( + "type", H5::PredType::STD_I32LE, H5::DataSpace(H5S_SCALAR))); attr_space_type.write(H5::PredType::STD_I32LE, &space_type); const double t = space.t(); - H5::Attribute attr_t( - root->createAttribute( - "t", H5::PredType::IEEE_F64LE, H5::DataSpace(H5S_SCALAR))); + H5::Attribute attr_t(root->createAttribute("t", H5::PredType::IEEE_F64LE, + H5::DataSpace(H5S_SCALAR))); attr_t.write(H5::PredType::IEEE_F64LE, &t); const Real3 edge_lengths = space.edge_lengths(); const hsize_t dims[] = {3}; const H5::ArrayType lengths_type(H5::PredType::NATIVE_DOUBLE, 1, dims); - H5::Attribute attr_lengths( - root->createAttribute( - "edge_lengths", lengths_type, H5::DataSpace(H5S_SCALAR))); + H5::Attribute attr_lengths(root->createAttribute( + "edge_lengths", lengths_type, H5::DataSpace(H5S_SCALAR))); double lengths[] = {edge_lengths[0], edge_lengths[1], edge_lengths[2]}; attr_lengths.write(lengths_type, lengths); const Integer3 matrix_sizes = space.matrix_sizes(); const H5::ArrayType sizes_type(H5::PredType::STD_I64LE, 1, dims); - H5::Attribute attr_sizes( - root->createAttribute( - "matrix_sizes", sizes_type, H5::DataSpace(H5S_SCALAR))); + H5::Attribute attr_sizes(root->createAttribute("matrix_sizes", sizes_type, + H5::DataSpace(H5S_SCALAR))); int64_t sizes[] = {matrix_sizes.col, matrix_sizes.row, matrix_sizes.layer}; attr_sizes.write(sizes_type, sizes); } -template -void load_subvolume_space(const H5::Group& root, Tspace_* space) +template +void load_subvolume_space(const H5::Group &root, Tspace_ *space) { typedef SubvolumeSpaceHDF5Traits traits_type; typedef typename traits_type::h5_species_struct h5_species_struct; @@ -231,8 +222,8 @@ void load_subvolume_space(const H5::Group& root, Tspace_* space) species_dset.getSpace().getSimpleExtentNpoints()); boost::scoped_array h5_species_table( new h5_species_struct[num_species]); - species_dset.read( - h5_species_table.get(), traits_type::get_species_comp_type()); + species_dset.read(h5_species_table.get(), + traits_type::get_species_comp_type()); species_dset.close(); H5::DataSet num_dset(root.openDataSet("num_molecules")); @@ -240,10 +231,9 @@ void load_subvolume_space(const H5::Group& root, Tspace_* space) num_dset.getSpace().getSimpleExtentDims(dims); assert(num_species == dims[0]); const unsigned int num_subvolumes(dims[1]); - boost::multi_array - h5_num_table(boost::extents[num_species][num_subvolumes]); - num_dset.read( - h5_num_table.data(), H5::PredType::STD_I64LE); + boost::multi_array h5_num_table( + boost::extents[num_species][num_subvolumes]); + num_dset.read(h5_num_table.data(), H5::PredType::STD_I64LE); num_dset.close(); typedef utils::get_mapper_mf::type @@ -251,7 +241,8 @@ void load_subvolume_space(const H5::Group& root, Tspace_* space) species_id_map_type species_id_map; for (unsigned int i(0); i < num_species; ++i) { - // species_id_map[h5_species_table[i].id] = h5_species_table[i].serial; + // species_id_map[h5_species_table[i].id] = + // h5_species_table[i].serial; species_id_map[h5_species_table[i].id] = i; } @@ -278,8 +269,8 @@ void load_subvolume_space(const H5::Group& root, Tspace_* space) structures_dset.getSpace().getSimpleExtentNpoints()); boost::scoped_array h5_structures_table( new h5_structures_struct[num_structures]); - structures_dset.read( - h5_structures_table.get(), traits_type::get_structures_comp_type()); + structures_dset.read(h5_structures_table.get(), + traits_type::get_structures_comp_type()); structures_dset.close(); H5::DataSet stcoordinate_dset(root.openDataSet("stcoordinates")); @@ -287,10 +278,10 @@ void load_subvolume_space(const H5::Group& root, Tspace_* space) stcoordinate_dset.getSpace().getSimpleExtentDims(dims); assert(num_structures == dims[0]); const unsigned int num_subvolumes(dims[1]); - boost::multi_array - h5_stcoordinate_table(boost::extents[num_structures][num_subvolumes]); - stcoordinate_dset.read( - h5_stcoordinate_table.data(), H5::PredType::IEEE_F64LE); + boost::multi_array h5_stcoordinate_table( + boost::extents[num_structures][num_subvolumes]); + stcoordinate_dset.read(h5_stcoordinate_table.data(), + H5::PredType::IEEE_F64LE); stcoordinate_dset.close(); typedef utils::get_mapper_mf::type @@ -298,7 +289,8 @@ void load_subvolume_space(const H5::Group& root, Tspace_* space) structures_id_map_type structures_id_map; for (unsigned int i(0); i < num_structures; ++i) { - structures_id_map[h5_structures_table[i].id] = h5_structures_table[i].serial; + structures_id_map[h5_structures_table[i].id] = + h5_structures_table[i].serial; } for (unsigned int i(0); i < num_structures; ++i) @@ -313,6 +305,6 @@ void load_subvolume_space(const H5::Group& root, Tspace_* space) } } -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_SUBVOLUME_SPACE_HDF5_WRITER_HPP */ diff --git a/ecell4/core/VacantType.hpp b/ecell4/core/VacantType.hpp index 1438efb66..a41ce499b 100644 --- a/ecell4/core/VacantType.hpp +++ b/ecell4/core/VacantType.hpp @@ -1,44 +1,35 @@ #ifndef ECELL4_VACANT_TYPE_HPP #define ECELL4_VACANT_TYPE_HPP -#include #include "StructureType.hpp" +#include namespace ecell4 { -class VacantType - : public StructureType +class VacantType : public StructureType { private: - typedef StructureType base_type; - VacantType() - : base_type(Species("", 0, 0), boost::weak_ptr(), 0) + VacantType() : base_type(Species("", 0, 0), boost::weak_ptr()) { ; // do nothing } public: - ~VacantType() { ; // do nothing } - voxel_type_type const voxel_type() const - { - return VACANT; - } + voxel_type_type const voxel_type() const { return VACANT; } - static - boost::shared_ptr - allocate() + static boost::shared_ptr allocate() { return boost::shared_ptr(new VacantType()); } }; -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_VACANT_TYPE_HPP */ diff --git a/ecell4/core/VoxelPool.hpp b/ecell4/core/VoxelPool.hpp index 7e893bdf0..c40c9ee59 100644 --- a/ecell4/core/VoxelPool.hpp +++ b/ecell4/core/VoxelPool.hpp @@ -1,15 +1,13 @@ #ifndef ECELL4_MOLECULAR_TYPE_BASE_HPP #define ECELL4_MOLECULAR_TYPE_BASE_HPP -#include -#include -#include -#include "Species.hpp" -#include "Shape.hpp" #include "Identifier.hpp" #include "RandomNumberGenerator.hpp" -#include "ParticleVoxel.hpp" - +#include "Shape.hpp" +#include "Species.hpp" +#include +#include +#include namespace ecell4 { @@ -17,62 +15,56 @@ namespace ecell4 class VoxelPool { public: - - typedef ParticleVoxel::coordinate_type coordinate_type; + typedef Integer coordinate_type; // typedef std::pair coordinate_id_pair_type; typedef struct coordinate_id_pair_type + { + coordinate_id_pair_type(ParticleID const &pid, + coordinate_type const &coordinate) + : coordinate(coordinate), pid(pid) { - coordinate_id_pair_type(ParticleID const& pid, coordinate_type const& coordinate) - : coordinate(coordinate), pid(pid) - {} - - coordinate_type coordinate; - ParticleID pid; - - bool operator==(const coordinate_id_pair_type& rhs) const - { - return pid == rhs.pid && - coordinate == rhs.coordinate; - } - - bool operator!=(const coordinate_id_pair_type& rhs) const - { - return pid != rhs.pid - || coordinate != rhs.coordinate; - } - - bool operator<(const coordinate_id_pair_type& rhs) const - { - return coordinate < rhs.coordinate - || (coordinate == rhs.coordinate && - pid < rhs.pid); - } - - bool operator>=(const coordinate_id_pair_type& rhs) const - { - return coordinate > rhs.coordinate - || (coordinate == rhs.coordinate && - pid >= rhs.pid); - } - - bool operator>(const coordinate_id_pair_type& rhs) const - { - return coordinate > rhs.coordinate - || (coordinate == rhs.coordinate && - pid > rhs.pid); - } - - bool operator<=(const coordinate_id_pair_type& rhs) const - { - return coordinate < rhs.coordinate - || (coordinate == rhs.coordinate && - pid <= rhs.pid); - } - } coordinate_id_pair_type; + } -public: + coordinate_type coordinate; + ParticleID pid; + bool operator==(const coordinate_id_pair_type &rhs) const + { + return pid == rhs.pid && coordinate == rhs.coordinate; + } + + bool operator!=(const coordinate_id_pair_type &rhs) const + { + return pid != rhs.pid || coordinate != rhs.coordinate; + } + + bool operator<(const coordinate_id_pair_type &rhs) const + { + return coordinate < rhs.coordinate || + (coordinate == rhs.coordinate && pid < rhs.pid); + } + + bool operator>=(const coordinate_id_pair_type &rhs) const + { + return coordinate > rhs.coordinate || + (coordinate == rhs.coordinate && pid >= rhs.pid); + } + + bool operator>(const coordinate_id_pair_type &rhs) const + { + return coordinate > rhs.coordinate || + (coordinate == rhs.coordinate && pid > rhs.pid); + } + + bool operator<=(const coordinate_id_pair_type &rhs) const + { + return coordinate < rhs.coordinate || + (coordinate == rhs.coordinate && pid <= rhs.pid); + } + } coordinate_id_pair_type; + +public: typedef enum { DEFAULT, @@ -82,100 +74,56 @@ class VoxelPool } voxel_type_type; public: - - VoxelPool( - const Species& species, boost::weak_ptr location, - const Real& radius, const Real& D) - : species_(species), location_(location), - radius_(radius), D_(D) + VoxelPool(const Species &species, boost::weak_ptr location) + : species_(species), location_(location) { ; } - - virtual ~VoxelPool() - { - ; - } + virtual ~VoxelPool() { ; } virtual voxel_type_type const voxel_type() const = 0; public: - bool is_vacant() const { - return voxel_type() == VACANT; + return voxel_type() == VACANT || location_.expired(); } - bool is_structure() const - { - return voxel_type() == STRUCTURE; - } + bool is_structure() const { return voxel_type() == STRUCTURE; } - bool is_interface() const - { - return voxel_type() == INTERFACE; - } + bool is_interface() const { return voxel_type() == INTERFACE; } - const Species& species() const - { - return species_; - } + const Species &species() const { return species_; } - boost::shared_ptr location() const - { - return location_.lock(); - } - - Real& radius() - { - return radius_; - } - - const Real& radius() const - { - return radius_; - } - - Real& D() - { - return D_; - } - - const Real& D() const - { - return D_; - } + boost::shared_ptr location() const { return location_.lock(); } public: - virtual const Integer size() const = 0; - virtual void add_voxel(const coordinate_id_pair_type& info) = 0; + virtual void add_voxel(const coordinate_id_pair_type &info) = 0; - virtual void replace_voxel( - const coordinate_type& from_coord, const coordinate_type& to_coord, - const std::size_t candidate = 0) + virtual void replace_voxel(const coordinate_type &from_coord, + const coordinate_type &to_coord, + const std::size_t candidate = 0) { ; // do nothing } - virtual coordinate_id_pair_type pop(const coordinate_type& coord) = 0; + virtual coordinate_id_pair_type pop(const coordinate_type &coord) = 0; - virtual bool remove_voxel_if_exists(const coordinate_type& coord) = 0; + virtual bool remove_voxel_if_exists(const coordinate_type &coord) = 0; - virtual const ParticleID get_particle_id(const coordinate_type& coord) const + virtual const ParticleID get_particle_id(const coordinate_type &coord) const { return ParticleID(); } protected: - const Species species_; boost::weak_ptr location_; - Real radius_, D_; }; -} // ecell4 +} // namespace ecell4 #endif diff --git a/ecell4/core/VoxelSpaceBase.cpp b/ecell4/core/VoxelSpaceBase.cpp index 2bb143844..a799e3b64 100644 --- a/ecell4/core/VoxelSpaceBase.cpp +++ b/ecell4/core/VoxelSpaceBase.cpp @@ -1,5 +1,5 @@ -#include "VoxelSpaceBase.hpp" #include "Context.hpp" +#include "VoxelSpaceBase.hpp" namespace ecell4 { @@ -16,11 +16,19 @@ std::vector VoxelSpaceBase::list_species() const return keys; } -Integer VoxelSpaceBase::num_molecules(const Species& sp) const +Integer VoxelSpaceBase::num_molecules(const Species &sp) const { Integer count(0); SpeciesExpressionMatcher sexp(sp); + { + const auto cnt = sexp.count(vacant_->species()); + if (cnt > 0) + { + count += vacant_->size() * cnt; + } + } + for (voxel_pool_map_type::const_iterator itr(voxel_pools_.begin()); itr != voxel_pools_.end(); ++itr) { @@ -37,89 +45,36 @@ Integer VoxelSpaceBase::num_molecules(const Species& sp) const const Integer cnt(sexp.count((*itr).first)); if (cnt > 0) { - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp((*itr).second); count += vp->size() * cnt; } } return count; } - -/* - * ParticleSpace Traits - */ - -std::vector > -VoxelSpaceBase::list_particles() const -{ - const std::vector > voxels(list_voxels()); - - std::vector > retval; - retval.reserve(voxels.size()); - for (std::vector >::const_iterator - i(voxels.begin()); i != voxels.end(); ++i) - { - const ParticleID& pid((*i).first); - const Particle p(particle_at((*i).second.coordinate)); - retval.push_back(std::make_pair(pid, p)); - } - return retval; -} - -std::vector > -VoxelSpaceBase::list_particles(const Species& sp) const -{ - const std::vector > voxels(list_voxels(sp)); - - std::vector > retval; - retval.reserve(voxels.size()); - for (std::vector >::const_iterator - i(voxels.begin()); i != voxels.end(); ++i) - { - const ParticleID& pid((*i).first); - const Particle p(particle_at((*i).second.coordinate)); - retval.push_back(std::make_pair(pid, p)); - } - return retval; -} - -std::vector > -VoxelSpaceBase::list_particles_exact(const Species& sp) const -{ - const std::vector > - voxels(list_voxels_exact(sp)); - - std::vector > retval; - retval.reserve(voxels.size()); - for (std::vector >::const_iterator - i(voxels.begin()); i != voxels.end(); ++i) - { - const ParticleID& pid((*i).first); - const Particle p(particle_at((*i).second.coordinate)); - retval.push_back(std::make_pair(pid, p)); - } - return retval; -} - - /* * VoxelSpace Traits */ -bool VoxelSpaceBase::has_voxel(const ParticleID& pid) const +bool VoxelSpaceBase::has_voxel(const ParticleID &pid) const { for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); itr != molecule_pools_.end(); ++itr) { - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp((*itr).second); if (vp->find(pid) != vp->end()) return true; } return false; } -Integer VoxelSpaceBase::num_voxels_exact(const Species& sp) const +Integer VoxelSpaceBase::num_voxels_exact(const Species &sp) const { + if (sp == vacant_->species()) + { + return vacant_->size(); + } + { voxel_pool_map_type::const_iterator itr(voxel_pools_.find(sp)); if (itr != voxel_pools_.end()) @@ -132,7 +87,7 @@ Integer VoxelSpaceBase::num_voxels_exact(const Species& sp) const molecule_pool_map_type::const_iterator itr(molecule_pools_.find(sp)); if (itr != molecule_pools_.end()) { - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp((*itr).second); return vp->size(); } } @@ -140,11 +95,16 @@ Integer VoxelSpaceBase::num_voxels_exact(const Species& sp) const return 0; } -Integer VoxelSpaceBase::num_voxels(const Species& sp) const +Integer VoxelSpaceBase::num_voxels(const Species &sp) const { Integer count(0); SpeciesExpressionMatcher sexp(sp); + if (sexp.match(vacant_->species())) + { + count += vacant_->size(); + } + for (voxel_pool_map_type::const_iterator itr(voxel_pools_.begin()); itr != voxel_pools_.end(); ++itr) { @@ -159,7 +119,7 @@ Integer VoxelSpaceBase::num_voxels(const Species& sp) const { if (sexp.match((*itr).first)) { - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp((*itr).second); count += vp->size(); } } @@ -170,6 +130,11 @@ Integer VoxelSpaceBase::num_voxels() const { Integer count(0); + if (vacant_->species().serial() != "") + { + count += vacant_->size(); + } + for (voxel_pool_map_type::const_iterator itr(voxel_pools_.begin()); itr != voxel_pools_.end(); ++itr) { @@ -179,69 +144,65 @@ Integer VoxelSpaceBase::num_voxels() const for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); itr != molecule_pools_.end(); ++itr) { - const boost::shared_ptr& vp((*itr).second); + const boost::shared_ptr &vp((*itr).second); count += vp->size(); } return count; } -void VoxelSpaceBase::push_voxels(std::vector >& voxels, - const boost::shared_ptr& voxel_pool, - const Species& species) const +static inline void +push_voxels(std::vector &voxels, + const boost::shared_ptr &voxel_pool) { - const std::string location_serial(get_location_serial(voxel_pool)); - for (MoleculePool::const_iterator i(voxel_pool->begin()); i != voxel_pool->end(); ++i) + for (const auto &voxel : *voxel_pool) + { voxels.push_back( - std::make_pair( - (*i).pid, - ParticleVoxel(species, (*i).coordinate, voxel_pool->radius(), - voxel_pool->D(), location_serial))); + VoxelView(voxel.pid, voxel_pool->species(), voxel.coordinate)); + } } -std::vector > -VoxelSpaceBase::list_voxels() const +std::vector VoxelSpaceBase::list_voxels() const { - std::vector > retval; + std::vector retval; for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); itr != molecule_pools_.end(); ++itr) { - const boost::shared_ptr& vp((*itr).second); - push_voxels(retval, vp, vp->species()); + const boost::shared_ptr &vp((*itr).second); + push_voxels(retval, vp); } return retval; } -std::vector > -VoxelSpaceBase::list_voxels(const Species& sp) const +std::vector VoxelSpaceBase::list_voxels(const Species &sp) const { - std::vector > retval; + std::vector retval; SpeciesExpressionMatcher sexp(sp); for (molecule_pool_map_type::const_iterator itr(molecule_pools_.begin()); - itr != molecule_pools_.end(); ++itr) + itr != molecule_pools_.end(); ++itr) if (sexp.match((*itr).first)) - push_voxels(retval, (*itr).second, sp); + push_voxels(retval, (*itr).second); return retval; } -std::vector > -VoxelSpaceBase::list_voxels_exact(const Species& sp) const +std::vector +VoxelSpaceBase::list_voxels_exact(const Species &sp) const { - std::vector > retval; + std::vector retval; molecule_pool_map_type::const_iterator itr(molecule_pools_.find(sp)); if (itr != molecule_pools_.end()) - push_voxels(retval, (*itr).second, sp); + push_voxels(retval, (*itr).second); return retval; } -boost::shared_ptr VoxelSpaceBase::find_voxel_pool(const Species& sp) +boost::shared_ptr VoxelSpaceBase::find_voxel_pool(const Species &sp) { - if (sp.serial() == "") + if (sp == vacant_->species()) return vacant_; voxel_pool_map_type::iterator itr(voxel_pools_.find(sp)); @@ -249,12 +210,13 @@ boost::shared_ptr VoxelSpaceBase::find_voxel_pool(const Species& sp) { return (*itr).second; } - return find_molecule_pool(sp); // upcast + return find_molecule_pool(sp); // upcast } -boost::shared_ptr VoxelSpaceBase::find_voxel_pool(const Species& sp) const +boost::shared_ptr +VoxelSpaceBase::find_voxel_pool(const Species &sp) const { - if (sp.serial() == "") + if (sp == vacant_->species()) return vacant_; voxel_pool_map_type::const_iterator itr(voxel_pools_.find(sp)); @@ -262,36 +224,38 @@ boost::shared_ptr VoxelSpaceBase::find_voxel_pool(const Species { return (*itr).second; } - return find_molecule_pool(sp); // upcast + return find_molecule_pool(sp); // upcast } -bool VoxelSpaceBase::has_molecule_pool(const Species& sp) const +bool VoxelSpaceBase::has_molecule_pool(const Species &sp) const { return (molecule_pools_.find(sp) != molecule_pools_.end()); } -boost::shared_ptr VoxelSpaceBase::find_molecule_pool(const Species& sp) +boost::shared_ptr +VoxelSpaceBase::find_molecule_pool(const Species &sp) { molecule_pool_map_type::iterator itr(molecule_pools_.find(sp)); if (itr != molecule_pools_.end()) { - return (*itr).second; // upcast + return (*itr).second; // upcast } throw NotFound("MoleculePool not found."); } -boost::shared_ptr VoxelSpaceBase::find_molecule_pool(const Species& sp) const +boost::shared_ptr +VoxelSpaceBase::find_molecule_pool(const Species &sp) const { molecule_pool_map_type::const_iterator itr(molecule_pools_.find(sp)); if (itr != molecule_pools_.end()) { - return (*itr).second; // upcast + return (*itr).second; // upcast } throw NotFound("MoleculePool not found."); } -bool VoxelSpaceBase::make_molecular_type( - const Species& sp, Real radius, Real D, const std::string loc) +bool VoxelSpaceBase::make_molecular_type(const Species &sp, + const std::string loc) { molecule_pool_map_type::iterator itr(molecule_pools_.find(sp)); if (itr != molecule_pools_.end()) @@ -300,14 +264,15 @@ bool VoxelSpaceBase::make_molecular_type( } else if (voxel_pools_.find(sp) != voxel_pools_.end()) { - throw IllegalState( - "The given species is already assigned to the VoxelPool with no voxels."); + throw IllegalState("The given species is already assigned to the " + "VoxelPool with no voxels."); } - boost::shared_ptr vp(new MoleculePool(sp, find_voxel_pool(Species(loc)), radius, D)); + boost::shared_ptr vp( + new MoleculePool(sp, find_voxel_pool(Species(loc)))); - std::pair - retval(molecule_pools_.insert(molecule_pool_map_type::value_type(sp, vp))); + std::pair retval( + molecule_pools_.insert(molecule_pool_map_type::value_type(sp, vp))); if (!retval.second) { @@ -316,7 +281,8 @@ bool VoxelSpaceBase::make_molecular_type( return retval.second; } -bool VoxelSpaceBase::make_structure_type(const Species& sp, const std::string loc) +bool VoxelSpaceBase::make_structure_type(const Species &sp, + const std::string loc) { voxel_pool_map_type::iterator itr(voxel_pools_.find(sp)); if (itr != voxel_pools_.end()) @@ -329,10 +295,10 @@ bool VoxelSpaceBase::make_structure_type(const Species& sp, const std::string lo "The given species is already assigned to the MoleculePool."); } - boost::shared_ptr - vp(new StructureType(sp, find_voxel_pool(Species(loc)), voxel_radius_)); - std::pair - retval(voxel_pools_.insert(voxel_pool_map_type::value_type(sp, vp))); + boost::shared_ptr vp( + new StructureType(sp, find_voxel_pool(Species(loc)))); + std::pair retval( + voxel_pools_.insert(voxel_pool_map_type::value_type(sp, vp))); if (!retval.second) { throw AlreadyExists("never reach here."); @@ -340,33 +306,4 @@ bool VoxelSpaceBase::make_structure_type(const Species& sp, const std::string lo return retval.second; } -boost::shared_ptr -VoxelSpaceBase::get_voxel_pool(ParticleVoxel voxel) -{ - const Species& sp(voxel.species); - - try - { - return find_voxel_pool(sp); - } - catch (const NotFound &_e) - { - // Create a new molecular pool - - if (!make_molecular_type(sp, voxel.radius, voxel.D, voxel.loc)) - { - throw IllegalState("never reach here"); - } - - molecule_pool_map_type::iterator itr = molecule_pools_.find(sp); - - if (itr == molecule_pools_.end()) - { - throw IllegalState("never reach here"); - } - - return itr->second; - } -} - -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/core/VoxelSpaceBase.hpp b/ecell4/core/VoxelSpaceBase.hpp index 713cd0b0d..49f548dd6 100644 --- a/ecell4/core/VoxelSpaceBase.hpp +++ b/ecell4/core/VoxelSpaceBase.hpp @@ -1,28 +1,26 @@ #ifndef ECELL4_VOXELSPACEBASE_HPP #define ECELL4_VOXELSPACEBASE_HPP -#include -#include +#include #include +#include #include -#include +#include -#include "Shape.hpp" -// #include "Space.hpp" +#include "Context.hpp" #include "Integer3.hpp" +#include "MoleculePool.hpp" +#include "Particle.hpp" +#include "Shape.hpp" +#include "VacantType.hpp" +#include "VoxelPool.hpp" +#include "VoxelView.hpp" #include "get_mapper_mf.hpp" -#include "Context.hpp" #ifdef WITH_HDF5 #include "LatticeSpaceHDF5Writer.hpp" #endif -#include "VoxelPool.hpp" -#include "MoleculePool.hpp" -#include "VacantType.hpp" -#include "ParticleVoxel.hpp" -#include "Particle.hpp" - namespace ecell4 { @@ -34,38 +32,35 @@ double round(const double x); template static inline std::string get_location_serial(T vp) { - if (vp == NULL || vp->location() == NULL || vp->location()->is_vacant()) { + if (vp == NULL || vp->location() == NULL || vp->location()->is_vacant()) + { return ""; } return vp->location()->species().serial(); } - class VoxelSpaceBase - // : public Space { public: - - typedef ParticleVoxel::coordinate_type coordinate_type; + typedef Integer coordinate_type; typedef VoxelPool::coordinate_id_pair_type coordinate_id_pair_type; protected: + typedef utils::get_mapper_mf>::type + voxel_pool_map_type; - typedef utils::get_mapper_mf >::type - voxel_pool_map_type; - - typedef utils::get_mapper_mf >::type - molecule_pool_map_type; + typedef utils::get_mapper_mf>::type + molecule_pool_map_type; public: - /* * Constructor and Destructor */ - VoxelSpaceBase(const Real& voxel_radius) : - t_(0.0), voxel_radius_(voxel_radius), vacant_(VacantType::allocate()) - {} + VoxelSpaceBase(const Real &voxel_radius) + : t_(0.0), voxel_radius_(voxel_radius), vacant_(VacantType::allocate()) + { + } virtual ~VoxelSpaceBase() {} @@ -73,26 +68,21 @@ class VoxelSpaceBase * Static Members */ - static inline - Real - calculate_voxel_volume(const Real r) + static inline Real calculate_voxel_volume(const Real r) { return 4.0 * sqrt(2.0) * r * r * r; } - static inline - Real3 - calculate_hcp_lengths(const Real voxel_radius) + static inline Real3 calculate_hcp_lengths(const Real voxel_radius) { - return Real3( - voxel_radius / sqrt(3.0), // HCP_L - voxel_radius * sqrt(8.0 / 3.0), // HCP_X - voxel_radius * sqrt(3.0)); // HCP_Y + return Real3(voxel_radius / sqrt(3.0), // HCP_L + voxel_radius * sqrt(8.0 / 3.0), // HCP_X + voxel_radius * sqrt(3.0)); // HCP_Y } - static inline - Integer3 - calculate_shape(const Real3& edge_lengths, const Real& voxel_radius, const bool is_periodic) + static inline Integer3 calculate_shape(const Real3 &edge_lengths, + const Real &voxel_radius, + const bool is_periodic) { const Real3 hcpLXY = calculate_hcp_lengths(voxel_radius); const Real lengthX = edge_lengths[0]; @@ -105,7 +95,8 @@ class VoxelSpaceBase if (is_periodic) { - // The number of voxels in each axis must be even for a periodic boundary. + // The number of voxels in each axis must be even for a periodic + // boundary. col_size = (col_size % 2 == 0 ? col_size : col_size + 1); layer_size = (layer_size % 2 == 0 ? layer_size : layer_size + 1); row_size = (row_size % 2 == 0 ? row_size : row_size + 1); @@ -114,26 +105,23 @@ class VoxelSpaceBase return Integer3(col_size, row_size, layer_size); } - static inline - Real - calculate_volume(const Real3& edge_lengths, const Real& voxel_radius, const bool is_periodic) + static inline Real calculate_volume(const Real3 &edge_lengths, + const Real &voxel_radius, + const bool is_periodic) { - const Integer3 shape = calculate_shape(edge_lengths, voxel_radius, is_periodic); - return static_cast(shape[0] * shape[1] * shape[2]) - * calculate_voxel_volume(voxel_radius); + const Integer3 shape = + calculate_shape(edge_lengths, voxel_radius, is_periodic); + return static_cast(shape[0] * shape[1] * shape[2]) * + calculate_voxel_volume(voxel_radius); } - /* * Space Traits */ - const Real t() const - { - return t_; - } + const Real t() const { return t_; } - void set_t(const Real& t) + void set_t(const Real &t) { if (t < 0.0) { @@ -146,7 +134,7 @@ class VoxelSpaceBase * get the axes lengths of a cuboidal region. * @return edge lengths Real3 */ - virtual const Real3& edge_lengths() const + virtual const Real3 &edge_lengths() const { throw NotSupported( "edge_lengths() is not supported by this space class"); @@ -156,167 +144,87 @@ class VoxelSpaceBase * get volume. * @return a volume (m^3) Real */ - const Real volume() const - { - return actual_size() * voxel_volume(); - } + const Real volume() const { return actual_size() * voxel_volume(); } - virtual void save(const std::string& filename) const + virtual void save(const std::string &filename) const { throw NotSupported( "save(const std::string) is not supported by this space class"); } #ifdef WITH_HDF5 - virtual void save_hdf5(H5::Group* root) const + virtual void save_hdf5(H5::Group *root) const { throw NotSupported( "save_hdf5(H5::Group* root) is not supported by this space class"); } - virtual void load_hdf5(const H5::Group& root) + virtual void load_hdf5(const H5::Group &root) { - throw NotSupported( - "load_hdf5(const H5::Group& root) is not supported by this space class"); + throw NotSupported("load_hdf5(const H5::Group& root) is not supported " + "by this space class"); } #endif - /* * CompartmentSpace Traits */ std::vector list_species() const; - bool has_species(const Species& sp) const + bool has_species(const Species &sp) const { - return (voxel_pools_.find(sp) != voxel_pools_.end() - || molecule_pools_.find(sp) != molecule_pools_.end()); + return num_voxels_exact(sp) != 0; } - virtual Integer num_molecules(const Species& sp) const; + virtual Integer num_molecules(const Species &sp) const; - virtual Integer num_molecules_exact(const Species& sp) const + virtual Integer num_molecules_exact(const Species &sp) const { return num_voxels_exact(sp); } - Real get_value(const Species& sp) const - { - return static_cast(num_molecules(sp)); - } - - Real get_value_exact(const Species& sp) const - { - return static_cast(num_molecules_exact(sp)); - } - - /* - * ParticleSpace Traits + * VoxelSpace Traits */ - Integer num_particles() const - { - return num_voxels(); - } + Real voxel_radius() const { return voxel_radius_; } - Integer num_particles(const Species& sp) const - { - return num_voxels(sp); - } + Real voxel_volume() const { return calculate_voxel_volume(voxel_radius_); } - Integer num_particles_exact(const Species& sp) const + Real get_volume(const Species &sp) const { - return num_voxels_exact(sp); + return voxel_volume() * num_voxels_exact(sp); } - bool has_particle(const ParticleID& pid) const + Real unit_area() const { - return has_voxel(pid); + const Real r(voxel_radius_); + return 2.0 * sqrt(3.0) * r * r; } - virtual - std::vector > - list_particles() const; - - virtual - std::vector > - list_particles(const Species& sp) const; + boost::shared_ptr vacant() { return vacant_; } - virtual - std::vector > - list_particles_exact(const Species& sp) const; + boost::shared_ptr vacant() const { return vacant_; } - virtual - std::pair - get_particle(const ParticleID& pid) const + boost::optional find_voxel(const ParticleID &pid) const { for (const auto &key_value : molecule_pools_) { - const auto &species(key_value.first); const auto &pool(key_value.second); - const auto j(pool->find(pid)); - if (j != pool->end()) + const auto itr(pool->find(pid)); + if (itr != pool->end()) { - return std::make_pair( - pid, - Particle( - species, - coordinate2position(j->coordinate), - pool->radius(), - pool->D() - ) - ); + return VoxelView(pid, pool->species(), itr->coordinate); } } - - throw NotFound(""); - } - - virtual const Particle particle_at(const coordinate_type& coord) const = 0; - - virtual bool remove_particle(const ParticleID& pid) - { - return remove_voxel(pid); - } - - /* - * VoxelSpace Traits - */ - Real voxel_radius() const - { - return voxel_radius_; - } - - Real voxel_volume() const - { - return calculate_voxel_volume(voxel_radius_); - } - - Real get_volume(const Species& sp) const - { - return voxel_volume() * num_voxels_exact(sp); - } - - Real unit_area() const - { - const Real r(voxel_radius_); - return 2.0 * sqrt(3.0) * r * r; - } - - boost::shared_ptr vacant() { - return vacant_; - } - - boost::shared_ptr vacant() const { - return vacant_; + return boost::none; } - boost::optional get_coordinate(const ParticleID& pid) const + boost::optional get_coordinate(const ParticleID &pid) const { - for (const auto& key_value : molecule_pools_) + for (const auto &key_value : molecule_pools_) { - const auto& pool(key_value.second); + const auto &pool(key_value.second); const auto itr(pool->find(pid)); if (itr != pool->end()) return itr->coordinate; @@ -324,92 +232,82 @@ class VoxelSpaceBase return boost::none; } - bool has_voxel(const ParticleID& pid) const; - Integer num_voxels_exact(const Species& sp) const; - Integer num_voxels(const Species& sp) const; + bool has_voxel(const ParticleID &pid) const; + Integer num_voxels_exact(const Species &sp) const; + Integer num_voxels(const Species &sp) const; Integer num_voxels() const; - virtual std::vector > list_voxels() const; - virtual std::vector > list_voxels(const Species& sp) const; - virtual std::vector > list_voxels_exact(const Species& sp) const; + virtual std::vector list_voxels() const; + virtual std::vector list_voxels(const Species &sp) const; + virtual std::vector list_voxels_exact(const Species &sp) const; - virtual std::pair get_voxel_at(const coordinate_type& coord) const = 0; + VoxelView get_voxel_at(const coordinate_type &coord) const + { + boost::shared_ptr vp(get_voxel_pool_at(coord)); + return VoxelView(vp->get_particle_id(coord), vp->species(), coord); + } - boost::shared_ptr find_voxel_pool(const Species& sp); - boost::shared_ptr find_voxel_pool(const Species& sp) const; + boost::shared_ptr find_voxel_pool(const Species &sp); + boost::shared_ptr find_voxel_pool(const Species &sp) const; - bool has_molecule_pool(const Species& sp) const; + bool has_molecule_pool(const Species &sp) const; - boost::shared_ptr find_molecule_pool(const Species& sp); - boost::shared_ptr find_molecule_pool(const Species& sp) const; + boost::shared_ptr find_molecule_pool(const Species &sp); + boost::shared_ptr + find_molecule_pool(const Species &sp) const; - virtual boost::shared_ptr get_voxel_pool_at(const coordinate_type& coord) const = 0; + virtual boost::shared_ptr + get_voxel_pool_at(const coordinate_type &coord) const = 0; /* * Coordinate Transformation */ - virtual Real3 coordinate2position(const coordinate_type& coord) const = 0; - virtual coordinate_type position2coordinate(const Real3& pos) const = 0; + virtual Real3 coordinate2position(const coordinate_type &coord) const = 0; + virtual coordinate_type position2coordinate(const Real3 &pos) const = 0; /* * Neighbor */ - virtual Integer num_neighbors(const coordinate_type& coord) const = 0; + virtual Integer num_neighbors(const coordinate_type &coord) const = 0; - virtual coordinate_type - get_neighbor(const coordinate_type& coord, const Integer& nrand) const = 0; + virtual coordinate_type get_neighbor(const coordinate_type &coord, + const Integer &nrand) const = 0; /* - * ParticleVoxel Manipulation + * Voxel Manipulation */ - virtual bool update_voxel(const ParticleID& pid, ParticleVoxel v) = 0; - virtual bool add_voxel(const Species& species, const ParticleID& pid, const coordinate_type& coord) = 0; - virtual bool remove_voxel(const ParticleID& pid) = 0; - virtual bool remove_voxel(const coordinate_type& coord) = 0; + virtual bool update_voxel(const ParticleID &pid, const Species &species, + const coordinate_type coordinate) = 0; + virtual bool add_voxel(const Species &species, const ParticleID &pid, + const coordinate_type &coord) = 0; + virtual bool remove_voxel(const ParticleID &pid) = 0; + virtual bool remove_voxel(const coordinate_type &coord) = 0; - virtual bool can_move(const coordinate_type& src, const coordinate_type& dest) const = 0; + virtual bool can_move(const coordinate_type &src, + const coordinate_type &dest) const = 0; - virtual - bool - move(const coordinate_type& src, const coordinate_type& dest, - const std::size_t candidate=0) - = 0; + virtual bool move(const coordinate_type &src, const coordinate_type &dest, + const std::size_t candidate = 0) = 0; virtual Integer size() const = 0; virtual Integer3 shape() const = 0; virtual Integer actual_size() const = 0; - bool - make_molecular_type(const Species& sp, Real radius, Real D, const std::string loc); - - bool - make_structure_type(const Species& sp, const std::string loc); + bool make_molecular_type(const Species &sp, const std::string loc); + bool make_structure_type(const Species &sp, const std::string loc); - virtual bool is_inside(const coordinate_type& coord) const - { - return true; - } + virtual bool is_inside(const coordinate_type &coord) const { return true; } protected: - - boost::shared_ptr get_voxel_pool(ParticleVoxel v); - - void push_voxels(std::vector >& voxels, - const boost::shared_ptr& voxel_pool, - const Species& species) const; - -protected: - Real t_; Real voxel_radius_; boost::shared_ptr vacant_; - voxel_pool_map_type voxel_pools_; + voxel_pool_map_type voxel_pools_; molecule_pool_map_type molecule_pools_; - }; -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_VOXELSPACEBASE_HPP */ diff --git a/ecell4/core/VoxelView.hpp b/ecell4/core/VoxelView.hpp new file mode 100644 index 000000000..7cc46408b --- /dev/null +++ b/ecell4/core/VoxelView.hpp @@ -0,0 +1,28 @@ +#ifndef ECELL4_VOXELVIEW_HPP +#define ECELL4_VOXELVIEW_HPP + +#include "Identifier.hpp" +#include "Species.hpp" +#include "types.hpp" + +namespace ecell4 +{ + +template +struct ParticleBase +{ + ParticleID pid; + const Species &species; + T voxel; + + ParticleBase(ParticleID pid, const Species &species, T voxel) + : pid(pid), species(species), voxel(voxel) + { + } +}; + +using VoxelView = ParticleBase; + +} // namespace ecell4 + +#endif /* ECELL4_VOXELVIEW_HPP */ diff --git a/ecell4/core/tests/LatticeSpace_test.cpp b/ecell4/core/tests/LatticeSpace_test.cpp index c506351e8..c76855f7c 100644 --- a/ecell4/core/tests/LatticeSpace_test.cpp +++ b/ecell4/core/tests/LatticeSpace_test.cpp @@ -1,18 +1,18 @@ #define BOOST_TEST_MODULE "LatticeSpace_test" #ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -# include +#include #else -# define BOOST_TEST_NO_LIB -# include +#define BOOST_TEST_NO_LIB +#include #endif #include -#include -#include #include +#include #include +#include using namespace ecell4; @@ -24,26 +24,24 @@ struct Fixture SerialIDGenerator sidgen; const Real D, radius; const Species sp; - Fixture() : - edge_lengths(2.5e-8, 2.5e-8, 2.5e-8), - voxel_radius(2.5e-9), - space(edge_lengths, voxel_radius, false), - sidgen(), D(1e-12), radius(2.5e-9), - sp("A", 2.5e-9, 1e-12) + Fixture() + : edge_lengths(2.5e-8, 2.5e-8, 2.5e-8), voxel_radius(2.5e-9), + space(edge_lengths, voxel_radius, false), sidgen(), D(1e-12), + radius(2.5e-9), sp("A", 2.5e-9, 1e-12) { + space.make_molecular_type(sp, ""); } }; BOOST_FIXTURE_TEST_SUITE(suite, Fixture) -BOOST_AUTO_TEST_CASE(LatticeSpace_test_constructor) -{ - ; -} +BOOST_AUTO_TEST_CASE(LatticeSpace_test_constructor) { ; } BOOST_AUTO_TEST_CASE(CheckVacantSize) { BOOST_CHECK_EQUAL(space.actual_size(), space.vacant()->size()); + BOOST_CHECK_EQUAL(space.num_voxels_exact(Species("")), + space.vacant()->size()); } BOOST_AUTO_TEST_CASE(GetVoxel) @@ -52,26 +50,21 @@ BOOST_AUTO_TEST_CASE(GetVoxel) const Integer coordinate(space.position2coordinate(position)); { - std::pair voxel(space.get_voxel_at(coordinate)); - BOOST_CHECK_EQUAL(voxel.first, ParticleID()); - BOOST_CHECK_EQUAL(voxel.second.species, space.vacant()->species()); + const auto view(space.get_voxel_at(coordinate)); + BOOST_CHECK_EQUAL(view.pid, ParticleID()); + BOOST_CHECK_EQUAL(view.species, space.vacant()->species()); } ParticleID id(sidgen()); - BOOST_CHECK(space.update_voxel(id, ParticleVoxel(sp, coordinate, radius, D))); + BOOST_CHECK(space.update_voxel(id, sp, coordinate)); { - std::pair voxel(space.get_voxel_at(coordinate)); - BOOST_CHECK_EQUAL(voxel.first, id); - BOOST_CHECK_EQUAL(voxel.second.species, sp); + const auto view(space.get_voxel_at(coordinate)); + BOOST_CHECK_EQUAL(view.pid, id); + BOOST_CHECK_EQUAL(view.species, sp); } } -BOOST_AUTO_TEST_CASE(LatticeSpace_test_num_species) -{ - BOOST_CHECK_EQUAL(space.num_species(), 0); -} - BOOST_AUTO_TEST_CASE(LatticeSpace_test_has_species) { BOOST_CHECK(!space.has_species(sp)); @@ -85,64 +78,59 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_update_particle) Real r(1.0); // Real d(2.3); // Particle particle(sp, pos, r, d); - ParticleVoxel v(sp, space.position2coordinate(pos), r, D); // BOOST_CHECK(space.update_particle(id, particle)); - BOOST_CHECK(space.update_voxel(id, v)); + BOOST_CHECK(space.update_voxel(id, sp, space.position2coordinate(pos))); BOOST_CHECK(space.has_species(sp)); } -BOOST_AUTO_TEST_CASE(LatticeSpace_test_num_particles) +BOOST_AUTO_TEST_CASE(LatticeSpace_test_num_voxels) { ParticleID id(sidgen()); Real3 pos(2e-8, 1.7e-8, 1.5e-8); Real r(1.0); // Real d(2.3); // Particle particle(sp, pos, r, d); - ParticleVoxel v(sp, space.position2coordinate(pos), r, D); ParticleID a_id(sidgen()); Species a(std::string("ANOTHER")); Real3 pos1(1e-8, 2e-8, 1e-9); Real r1(1.1); Real d1(4.3); + BOOST_CHECK(space.make_molecular_type(a, "")); // Particle another(a, pos1, r1, d1); - ParticleVoxel another(a, space.position2coordinate(pos1), r1, d1); - BOOST_CHECK(space.update_voxel(id, v)); - BOOST_CHECK(space.update_voxel(a_id, another)); + BOOST_CHECK(space.update_voxel(id, sp, space.position2coordinate(pos))); + BOOST_CHECK(space.update_voxel(a_id, a, space.position2coordinate(pos1))); // BOOST_CHECK(space.update_particle(id, particle)); // BOOST_CHECK(space.update_particle(a_id, another)); - BOOST_CHECK_EQUAL(space.num_particles(sp), 1); - BOOST_CHECK_EQUAL(space.num_particles(), 2); + BOOST_CHECK_EQUAL(space.num_voxels(sp), 1); + BOOST_CHECK_EQUAL(space.num_voxels(), 2); } -BOOST_AUTO_TEST_CASE(LatticeSpace_test_list_particles) +BOOST_AUTO_TEST_CASE(LatticeSpace_test_list_voxels) { ParticleID id(sidgen()); Real3 pos(2e-8, 1.7e-8, 1.5e-8); Real r(1.0); // Real d(2.3); // Particle particle(sp, pos, r, d); - ParticleVoxel v(sp, space.position2coordinate(pos), r, D); ParticleID a_id(sidgen()); Species a(std::string("ANOTHER")); Real3 pos1(1e-8, 2e-8, 1e-9); Real r1(1.1); Real d1(4.3); + BOOST_CHECK(space.make_molecular_type(a, "")); // Particle another(a, pos1, r1, d1); - ParticleVoxel another(a, space.position2coordinate(pos1), r1, d1); - BOOST_CHECK(space.update_voxel(id, v)); - BOOST_CHECK(space.update_voxel(a_id, another)); + BOOST_CHECK(space.update_voxel(id, sp, space.position2coordinate(pos))); + BOOST_CHECK(space.update_voxel(a_id, a, space.position2coordinate(pos1))); // BOOST_CHECK(space.update_particle(id, particle)); // BOOST_CHECK(space.update_particle(a_id, another)); - typedef std::vector > vector; - - vector test_list(space.list_particles(sp)); - vector list(space.list_particles()); + const auto test_list(space.list_voxels(sp)); + const auto list(space.list_voxels()); BOOST_CHECK_EQUAL(list.size(), 2); BOOST_CHECK_EQUAL(test_list.size(), 1); } @@ -151,10 +139,10 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_list_particles) // { // BOOST_CHECK(space.register_species(sp)); // BOOST_CHECK(space.has_species(sp)); -// +// // std::vector list; // list.push_back(sp); -// +// // BOOST_CHECK(list == space.list_species()); // } @@ -163,7 +151,8 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_coordinate_global_translation) for (Integer coord(0); coord < space.size(); ++coord) { const Integer3 global(space.coordinate2global(coord)); - VoxelSpaceBase::coordinate_type created_coord(space.global2coordinate(global)); + VoxelSpaceBase::coordinate_type created_coord( + space.global2coordinate(global)); BOOST_CHECK_EQUAL(coord, created_coord); } } @@ -176,7 +165,7 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_coordinate_position_translation) BOOST_ASSERT(origin_pos[2] < 0); const VoxelSpaceBase::coordinate_type origin( - (space.col_size() + 3) * (space.row_size() + 2) + 1); + (space.col_size() + 3) * (space.row_size() + 2) + 1); const Real3 origin_p(space.coordinate2position(origin)); BOOST_ASSERT(origin_p[0] == 0); BOOST_ASSERT(origin_p[1] == 0); @@ -186,21 +175,21 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_coordinate_position_translation) for (Integer i(0); i < 12; ++i) { const Real3 neighbor( - space.coordinate2position(space.get_neighbor(origin, i))); + space.coordinate2position(space.get_neighbor(origin, i))); BOOST_CHECK(origin_p != neighbor); const VoxelSpaceBase::coordinate_type coord( - space.position2coordinate(origin_p * 0.7 + neighbor * 0.3)); + space.position2coordinate(origin_p * 0.7 + neighbor * 0.3)); BOOST_CHECK_EQUAL(origin, coord); } - Integer size( - (space.col_size()+2) * (space.layer_size() + 2) * (space.row_size() + 2)); + Integer size((space.col_size() + 2) * (space.layer_size() + 2) * + (space.row_size() + 2)); for (VoxelSpaceBase::coordinate_type coord(0); coord < size; ++coord) { const Real3 pos(space.coordinate2position(coord)); // const Integer3 global(space.position2global(pos)); const VoxelSpaceBase::coordinate_type created_coord( - space.position2coordinate(pos)); + space.position2coordinate(pos)); BOOST_CHECK_EQUAL(coord, created_coord); } } @@ -208,11 +197,10 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_coordinate_position_translation) BOOST_AUTO_TEST_CASE(LatticeSpace_test_add_remove_molecule) { const VoxelSpaceBase::coordinate_type coord( - space.global2coordinate(Integer3(3,4,5))); + space.global2coordinate(Integer3(3, 4, 5))); ParticleID pid(sidgen()); - BOOST_CHECK(space.update_voxel( - pid, ParticleVoxel(sp, coord, radius, D))); - BOOST_CHECK_EQUAL(space.num_particles(sp), 1); + BOOST_CHECK(space.update_voxel(pid, sp, coord)); + BOOST_CHECK_EQUAL(space.num_voxels(sp), 1); boost::shared_ptr mt(space.get_voxel_pool_at(coord)); BOOST_CHECK(!mt->is_vacant()); @@ -224,48 +212,46 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_add_remove_molecule) BOOST_AUTO_TEST_CASE(LatticeSpace_test_move) { - const Integer3 global0(2,3,4); + const Integer3 global0(2, 3, 4); const VoxelSpaceBase::coordinate_type coord( - space.global2coordinate(global0)); + space.global2coordinate(global0)); ParticleID pid(sidgen()); - BOOST_CHECK(space.update_voxel( - pid, ParticleVoxel(sp, coord, radius, D))); + BOOST_CHECK(space.update_voxel(pid, sp, coord)); boost::shared_ptr from_mt(space.get_voxel_pool_at(coord)); BOOST_CHECK(!from_mt->is_vacant()); - const Integer3 global1(2,4,4); + const Integer3 global1(2, 4, 4); const VoxelSpaceBase::coordinate_type to_coord( - space.global2coordinate(global1)); + space.global2coordinate(global1)); BOOST_CHECK(space.move(coord, to_coord)); boost::shared_ptr mt(space.get_voxel_pool_at(to_coord)); BOOST_CHECK(!mt->is_vacant()); - BOOST_CHECK(space.update_voxel( - sidgen(), ParticleVoxel(sp, coord, radius, D))); + BOOST_CHECK(space.update_voxel(sidgen(), sp, coord)); BOOST_CHECK(!space.move(coord, to_coord)); } BOOST_AUTO_TEST_CASE(LatticeSpace_test_update_molecule) { - Species reactant(std::string("Reactant")), - product(std::string("Product")); + Species reactant(std::string("Reactant")), product(std::string("Product")); - const Integer3 global(3,4,5); + const Integer3 global(3, 4, 5); const VoxelSpaceBase::coordinate_type coord( - space.global2coordinate(global)); + space.global2coordinate(global)); + + BOOST_CHECK(space.make_molecular_type(reactant, "")); + BOOST_CHECK(space.make_molecular_type(product, "")); ParticleID pid(sidgen()); - BOOST_CHECK(space.update_voxel( - pid, ParticleVoxel(reactant, coord, radius, D))); + BOOST_CHECK(space.update_voxel(pid, reactant, coord)); // space.update_voxel( // ParticleVoxel(product, coord, radius, D)); BOOST_CHECK(space.remove_voxel(coord)); - BOOST_CHECK(space.update_voxel( - pid, ParticleVoxel(product, coord, radius, D))); + BOOST_CHECK(space.update_voxel(pid, product, coord)); boost::shared_ptr mt(space.get_voxel_pool_at(coord)); BOOST_ASSERT(mt->species() == product); @@ -274,7 +260,8 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_update_molecule) BOOST_AUTO_TEST_CASE(LatticeSpace_test_update_voxel) { const ParticleID pid(sidgen()); - for (VoxelSpaceBase::coordinate_type coord(0); coord < space.size(); ++coord) + for (VoxelSpaceBase::coordinate_type coord(0); coord < space.size(); + ++coord) { if (!space.is_inside(coord)) { @@ -282,34 +269,34 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_update_voxel) } const Real3 pos(space.coordinate2position(coord)); - space.update_voxel(pid, ParticleVoxel(sp, coord, radius, D)); - BOOST_CHECK_EQUAL(space.num_particles(), 1); - - std::pair pair(space.list_particles()[0]); - BOOST_CHECK_EQUAL(pid, pair.first); - BOOST_CHECK_EQUAL(pos, pair.second.position()); - BOOST_CHECK_EQUAL(radius, pair.second.radius()); - BOOST_CHECK_EQUAL(D, pair.second.D()); - //BOOST_CHECK_EQUAL(sp, pair.second.species()); + space.update_voxel(pid, sp, coord); + BOOST_CHECK_EQUAL(space.num_voxels(), 1); + + const auto view(space.list_voxels()[0]); + BOOST_CHECK_EQUAL(pid, view.pid); + BOOST_CHECK_EQUAL(coord, view.voxel); + // BOOST_CHECK_EQUAL(sp, view.species); //[TODO] Species is not comparable. } } BOOST_AUTO_TEST_CASE(LatticeSpace_test_lattice_structure) { - for (VoxelSpaceBase::coordinate_type coord(0); coord < space.size(); ++coord) + for (VoxelSpaceBase::coordinate_type coord(0); coord < space.size(); + ++coord) { if (space.is_inside(coord)) { ParticleID pid(sidgen()); - BOOST_CHECK(space.update_voxel(pid, ParticleVoxel(sp, coord, radius, D))); + BOOST_CHECK(space.update_voxel(pid, sp, coord)); } } } BOOST_AUTO_TEST_CASE(LatticeSpace_test_neighbor) { - for (VoxelSpaceBase::coordinate_type coord(0); coord < space.size(); ++coord) + for (VoxelSpaceBase::coordinate_type coord(0); coord < space.size(); + ++coord) { if (!space.is_inside(coord)) { @@ -320,7 +307,8 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_neighbor) const Real3 center(space.coordinate2position(coord)); for (int i(0); i < 12; ++i) { - VoxelSpaceBase::coordinate_type neighbor(space.get_neighbor(coord, i)); + VoxelSpaceBase::coordinate_type neighbor( + space.get_neighbor(coord, i)); if (!space.is_inside(neighbor)) { continue; @@ -328,7 +316,7 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_neighbor) Real3 pos(space.coordinate2position(neighbor)); // Real3 vec((pos-center)/voxel_radius/2); - Real r_ratio(length(pos-center)/voxel_radius/2); + Real r_ratio(length(pos - center) / voxel_radius / 2); BOOST_ASSERT(r_ratio < 1.0001); } } @@ -344,13 +332,12 @@ struct PeriodicFixture SerialIDGenerator sidgen; const Real D, radius; const Species sp; - PeriodicFixture() : - edge_lengths(2.5e-8, 2.5e-8, 2.5e-8), - voxel_radius(2.5e-9), - space(edge_lengths, voxel_radius, true), - sidgen(), D(1e-12), radius(2.5e-9), - sp(std::string("A"), 2.5e-9, 1e-12) + PeriodicFixture() + : edge_lengths(2.5e-8, 2.5e-8, 2.5e-8), voxel_radius(2.5e-9), + space(edge_lengths, voxel_radius, true), sidgen(), D(1e-12), + radius(2.5e-9), sp(std::string("A"), 2.5e-9, 1e-12) { + space.make_molecular_type(sp, ""); } }; @@ -359,30 +346,30 @@ BOOST_FIXTURE_TEST_SUITE(periodic_suite, PeriodicFixture) BOOST_AUTO_TEST_CASE(LatticeSpace_test_periodic_col) { std::cerr << " < periodic_col > "; - const int col_size(space.col_size()), - row_size(space.row_size()), - layer_size(space.layer_size()); + const int col_size(space.col_size()), row_size(space.row_size()), + layer_size(space.layer_size()); for (int i(0); i < row_size; ++i) for (int j(0); j < layer_size; ++j) { - const VoxelSpaceBase::coordinate_type - coord(space.global2coordinate(Integer3(0, i, j))); + const VoxelSpaceBase::coordinate_type coord( + space.global2coordinate(Integer3(0, i, j))); - BOOST_CHECK(space.update_voxel(sidgen(), ParticleVoxel(sp, coord, radius, D))); + BOOST_CHECK(space.update_voxel(sidgen(), sp, coord)); } // from 0 to col_size-1 for (int i(0); i < row_size; ++i) for (int j(0); j < layer_size; ++j) { - const VoxelSpaceBase::coordinate_type - coord(space.global2coordinate(Integer3(0, i, j))); + const VoxelSpaceBase::coordinate_type coord( + space.global2coordinate(Integer3(0, i, j))); - const Integer nrnd((j&1)==1?2:3); - const VoxelSpaceBase::coordinate_type - neighbor(space.get_neighbor(coord, nrnd)); + const Integer nrnd((j & 1) == 1 ? 2 : 3); + const VoxelSpaceBase::coordinate_type neighbor( + space.get_neighbor(coord, nrnd)); - BOOST_CHECK_EQUAL(space.coordinate2global(neighbor).col, col_size-1); + BOOST_CHECK_EQUAL(space.coordinate2global(neighbor).col, + col_size - 1); BOOST_CHECK(space.move(coord, neighbor)); } @@ -390,12 +377,12 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_periodic_col) for (int i(0); i < row_size; ++i) for (int j(0); j < layer_size; ++j) { - const VoxelSpaceBase::coordinate_type - coord(space.global2coordinate(Integer3(col_size-1, i, j))); + const VoxelSpaceBase::coordinate_type coord( + space.global2coordinate(Integer3(col_size - 1, i, j))); - const Integer nrnd((j&1)==1?4:5); - const VoxelSpaceBase::coordinate_type - neighbor(space.get_neighbor(coord, nrnd)); + const Integer nrnd((j & 1) == 1 ? 4 : 5); + const VoxelSpaceBase::coordinate_type neighbor( + space.get_neighbor(coord, nrnd)); BOOST_CHECK_EQUAL(space.coordinate2global(neighbor).col, 0); BOOST_CHECK(space.move(coord, neighbor)); @@ -404,30 +391,30 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_periodic_col) BOOST_AUTO_TEST_CASE(LatticeSpace_test_periodic_row) { - const int col_size(space.col_size()), - row_size(space.row_size()), - layer_size(space.layer_size()); + const int col_size(space.col_size()), row_size(space.row_size()), + layer_size(space.layer_size()); for (int layer(0); layer < layer_size; ++layer) for (int col(0); col < col_size; ++col) { - const VoxelSpaceBase::coordinate_type - coord(space.global2coordinate(Integer3(col, 0, layer))); + const VoxelSpaceBase::coordinate_type coord( + space.global2coordinate(Integer3(col, 0, layer))); - BOOST_CHECK(space.update_voxel(sidgen(), ParticleVoxel(sp, coord, radius, D))); + BOOST_CHECK(space.update_voxel(sidgen(), sp, coord)); } // from 0 to row_size-1 for (int layer(0); layer < layer_size; ++layer) for (int col(0); col < col_size; ++col) { - const VoxelSpaceBase::coordinate_type - coord(space.global2coordinate(Integer3(col, 0, layer))); + const VoxelSpaceBase::coordinate_type coord( + space.global2coordinate(Integer3(col, 0, layer))); const Integer nrnd(0); - const VoxelSpaceBase::coordinate_type - neighbor(space.get_neighbor(coord, nrnd)); + const VoxelSpaceBase::coordinate_type neighbor( + space.get_neighbor(coord, nrnd)); - BOOST_CHECK_EQUAL(space.coordinate2global(neighbor).row, row_size-1); + BOOST_CHECK_EQUAL(space.coordinate2global(neighbor).row, + row_size - 1); BOOST_CHECK(space.move(coord, neighbor)); } // from row_size-1 to 0 @@ -435,10 +422,10 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_periodic_row) for (int col(0); col < col_size; ++col) { const VoxelSpaceBase::coordinate_type coord( - space.global2coordinate(Integer3(col, row_size-1, layer))); + space.global2coordinate(Integer3(col, row_size - 1, layer))); const Integer nrnd(1); - const VoxelSpaceBase::coordinate_type - neighbor(space.get_neighbor(coord, nrnd)); + const VoxelSpaceBase::coordinate_type neighbor( + space.get_neighbor(coord, nrnd)); BOOST_CHECK_EQUAL(space.coordinate2global(neighbor).row, 0); BOOST_CHECK(space.move(coord, neighbor)); @@ -447,31 +434,31 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_periodic_row) BOOST_AUTO_TEST_CASE(LatticeSpace_test_periodic_layer) { - const int col_size(space.col_size()), - row_size(space.row_size()), - layer_size(space.layer_size()); + const int col_size(space.col_size()), row_size(space.row_size()), + layer_size(space.layer_size()); for (int row(0); row < row_size; ++row) for (int col(0); col < col_size; ++col) { - const VoxelSpaceBase::coordinate_type - coord(space.global2coordinate(Integer3(col, row, 0))); + const VoxelSpaceBase::coordinate_type coord( + space.global2coordinate(Integer3(col, row, 0))); - BOOST_CHECK(space.update_voxel(sidgen(), ParticleVoxel(sp, coord, radius, D))); + BOOST_CHECK(space.update_voxel(sidgen(), sp, coord)); } // from 0 to layer_size-1 for (int row(0); row < row_size; ++row) for (int col(0); col < col_size; ++col) { - const VoxelSpaceBase::coordinate_type - coord(space.global2coordinate(Integer3(col, row, 0))); + const VoxelSpaceBase::coordinate_type coord( + space.global2coordinate(Integer3(col, row, 0))); - const Integer nrnd((col&1)==1?8:9); - const VoxelSpaceBase::coordinate_type - neighbor(space.get_neighbor(coord, nrnd)); + const Integer nrnd((col & 1) == 1 ? 8 : 9); + const VoxelSpaceBase::coordinate_type neighbor( + space.get_neighbor(coord, nrnd)); - BOOST_CHECK_EQUAL(space.coordinate2global(neighbor).layer, layer_size-1); + BOOST_CHECK_EQUAL(space.coordinate2global(neighbor).layer, + layer_size - 1); BOOST_CHECK(space.move(coord, neighbor)); } @@ -480,10 +467,10 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_periodic_layer) for (int col(0); col < col_size; ++col) { const VoxelSpaceBase::coordinate_type coord( - space.global2coordinate(Integer3(col, row, layer_size-1))); - const Integer nrnd((col&1)==1?10:11); - const VoxelSpaceBase::coordinate_type - neighbor(space.get_neighbor(coord, nrnd)); + space.global2coordinate(Integer3(col, row, layer_size - 1))); + const Integer nrnd((col & 1) == 1 ? 10 : 11); + const VoxelSpaceBase::coordinate_type neighbor( + space.get_neighbor(coord, nrnd)); BOOST_CHECK_EQUAL(space.coordinate2global(neighbor).layer, 0); BOOST_CHECK(space.move(coord, neighbor)); @@ -518,14 +505,14 @@ struct StructureFixture SerialIDGenerator sidgen; const Real D, radius; const Species structure, sp; - StructureFixture() : - edge_lengths(2.5e-8, 2.5e-8, 2.5e-8), - voxel_radius(2.5e-9), - space(edge_lengths, voxel_radius, false), - sidgen(), D(1e-12), radius(2.5e-9), - structure("Structure", 2.5e-9, 0), - sp("A", 2.5e-9, 1e-12, "Structure") + StructureFixture() + : edge_lengths(2.5e-8, 2.5e-8, 2.5e-8), voxel_radius(2.5e-9), + space(edge_lengths, voxel_radius, false), sidgen(), D(1e-12), + radius(2.5e-9), structure("Structure", 2.5e-9, 0), + sp("A", 2.5e-9, 1e-12, "Structure") { + space.make_structure_type(structure, ""); + space.make_molecular_type(sp, structure.serial()); } }; @@ -535,21 +522,22 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_structure_update) { const Real3 pos(2.7e-9, 1.3e-8, 2.0e-8); BOOST_CHECK(space.update_structure(Particle(structure, pos, radius, D))); - BOOST_CHECK_EQUAL(space.list_particles().size(), 1); + BOOST_CHECK_EQUAL(space.list_voxels().size(), 1); ParticleID pid(sidgen()); - //XXX: Particle has no information about the location. - //XXX: BOOST_CHECK(space.update_particle(pid, Particle(sp, pos, radius, D))); - BOOST_CHECK(space.update_voxel( - pid, ParticleVoxel(sp, space.position2coordinate(pos), radius, D, structure.serial()))); - BOOST_CHECK_EQUAL(space.list_particles().size(), 1); - BOOST_CHECK_EQUAL(space.list_particles(sp).size(), 1); - BOOST_CHECK(space.remove_particle(pid)); - BOOST_CHECK_EQUAL(space.list_particles().size(), 1); // TODO -> 0 - BOOST_CHECK_EQUAL(space.list_particles(sp).size(), 0); + // XXX: Particle has no information about the location. + // XXX: BOOST_CHECK(space.update_particle(pid, Particle(sp, pos, radius, + // D))); + BOOST_CHECK(space.update_voxel(pid, sp, space.position2coordinate(pos))); + BOOST_CHECK_EQUAL(space.list_voxels().size(), 1); + BOOST_CHECK_EQUAL(space.list_voxels(sp).size(), 1); + BOOST_CHECK(space.remove_voxel(pid)); + BOOST_CHECK_EQUAL(space.list_voxels().size(), 1); // TODO -> 0 + BOOST_CHECK_EQUAL(space.list_voxels(sp).size(), 0); Species sp2("B", 2.5e-9, 1e-12); + BOOST_CHECK(space.make_molecular_type(sp2, "")); BOOST_CHECK_THROW( - space.update_voxel(sidgen(), ParticleVoxel(sp2, space.position2coordinate(pos), radius, D)), + space.update_voxel(sidgen(), sp2, space.position2coordinate(pos)), NotSupported); // BOOST_CHECK_THROW( // space.update_particle(sidgen(), Particle(sp2, pos, radius, D)), @@ -561,24 +549,25 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_structure_move) const Real3 pos1(2.7e-9, 1.3e-8, 2.0e-8); const Real3 pos2(1.2e-8, 1.5e-8, 1.8e-8); BOOST_CHECK(space.update_structure(Particle(structure, pos1, radius, D))); - BOOST_CHECK_EQUAL(space.list_particles().size(), 1); + BOOST_CHECK_EQUAL(space.list_voxels().size(), 1); BOOST_CHECK(space.update_structure(Particle(structure, pos2, radius, D))); - BOOST_CHECK_EQUAL(space.list_particles().size(), 2); // TODO -> 0 + BOOST_CHECK_EQUAL(space.list_voxels().size(), 2); // TODO -> 0 + BOOST_CHECK_EQUAL(space.list_voxels().size(), 2); // TODO -> 0 ParticleID pid(sidgen()); - //XXX: BOOST_CHECK(space.update_particle(pid, Particle(sp, pos1, radius, D))); - BOOST_CHECK(space.update_voxel( - pid, ParticleVoxel(sp, space.position2coordinate(pos1), radius, D, structure.serial()))); - BOOST_CHECK_EQUAL(space.list_particles(sp).size(), 1); - BOOST_CHECK_EQUAL(space.list_particles(structure).size(), 1); - BOOST_CHECK_EQUAL(space.list_particles().size(), 2); // TODO -> 1 - const VoxelSpaceBase::coordinate_type - coord1(space.position2coordinate(pos1)), + // XXX: BOOST_CHECK(space.update_particle(pid, Particle(sp, pos1, radius, + // D))); + BOOST_CHECK(space.update_voxel(pid, sp, space.position2coordinate(pos1))); + BOOST_CHECK_EQUAL(space.list_voxels(sp).size(), 1); + BOOST_CHECK_EQUAL(space.list_voxels(structure).size(), 1); + BOOST_CHECK_EQUAL(space.list_voxels().size(), 2); // TODO -> 1 + const VoxelSpaceBase::coordinate_type coord1( + space.position2coordinate(pos1)), coord2(space.position2coordinate(pos2)); BOOST_CHECK(space.move(coord1, coord2)); - BOOST_CHECK_EQUAL(space.list_particles(sp).size(), 1); - BOOST_CHECK_EQUAL(space.list_particles(structure).size(), 1); - BOOST_CHECK_EQUAL(space.list_particles().size(), 2); // TODO -> 1 + BOOST_CHECK_EQUAL(space.list_voxels(sp).size(), 1); + BOOST_CHECK_EQUAL(space.list_voxels(structure).size(), 1); + BOOST_CHECK_EQUAL(space.list_voxels().size(), 2); // TODO -> 1 } #ifdef WITH_HDF5 @@ -586,25 +575,28 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_save_and_load) { space.make_structure_type(structure, ""); - const Integer l(space.layer_size()/2); + const Integer l(space.layer_size() / 2); for (int c(0); c < space.col_size(); ++c) for (int r(0); r < space.row_size(); ++r) { const Real3 pos(space.global2position(Integer3(c, r, l))); - BOOST_ASSERT(space.update_structure(Particle(structure, pos, radius, D))); + BOOST_ASSERT( + space.update_structure(Particle(structure, pos, radius, D))); } - const VoxelSpaceBase::coordinate_type - center(space.global2coordinate(Integer3(space.col_size()/2, space.row_size()/2, l))), - point(space.global2coordinate(Integer3(space.col_size()/2, space.row_size()/2, l-2))); - BOOST_ASSERT(space.update_voxel(sidgen(), ParticleVoxel(sp, center, radius, D, structure.serial()))); - // #XXX !!!Warning!!! Ideally, not necessary to give structure.serial() explicitly - BOOST_ASSERT(space.update_voxel(sidgen(), ParticleVoxel( - Species("B", 2.5e-9, 1e-12), point, 2.5e-9, 1e-12))); + const VoxelSpaceBase::coordinate_type center(space.global2coordinate( + Integer3(space.col_size() / 2, space.row_size() / 2, l))), + point(space.global2coordinate( + Integer3(space.col_size() / 2, space.row_size() / 2, l - 2))); + BOOST_ASSERT(space.update_voxel(sidgen(), sp, center)); + // #XXX !!!Warning!!! Ideally, not necessary to give structure.serial() + // explicitly + BOOST_ASSERT( + space.update_voxel(sidgen(), Species("B", 2.5e-9, 1e-12), point)); H5::H5File fout("data.h5", H5F_ACC_TRUNC); - boost::scoped_ptr - group(new H5::Group(fout.createGroup("VoxelSpaceBase"))); + boost::scoped_ptr group( + new H5::Group(fout.createGroup("VoxelSpaceBase"))); space.save_hdf5(group.get()); fout.close(); @@ -618,23 +610,19 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_save_and_load) BOOST_CHECK_EQUAL(space.voxel_radius(), space2.voxel_radius()); BOOST_CHECK_EQUAL(space.is_periodic(), space2.is_periodic()); BOOST_CHECK_EQUAL(space.t(), space2.t()); - BOOST_CHECK_EQUAL(space.num_particles(), space2.num_particles()); - BOOST_CHECK_EQUAL(space.num_species(), space2.num_species()); + BOOST_CHECK_EQUAL(space.num_voxels(), space2.num_voxels()); std::vector species(space.list_species()); for (std::vector::const_iterator itr(species.begin()); - itr != species.end(); ++itr) + itr != species.end(); ++itr) { const Species species((*itr).serial()); boost::shared_ptr vp1(space.find_voxel_pool(species)); boost::shared_ptr vp2(space2.find_voxel_pool(species)); - BOOST_CHECK_EQUAL(vp1->radius(), vp2->radius()); - BOOST_CHECK_EQUAL(vp1->D(), vp2->D()); - - const MoleculePool* mtb1(dynamic_cast(vp1.get())); - const MoleculePool* mtb2(dynamic_cast(vp2.get())); + const MoleculePool *mtb1(dynamic_cast(vp1.get())); + const MoleculePool *mtb2(dynamic_cast(vp2.get())); BOOST_ASSERT((mtb1 && mtb2) || (!mtb1 && !mtb2)); if (!mtb1 || !mtb2) @@ -648,10 +636,12 @@ BOOST_AUTO_TEST_CASE(LatticeSpace_test_save_and_load) BOOST_ASSERT(voxels1.size() == voxels2.size()); std::sort(voxels1.begin(), voxels1.end()); std::sort(voxels2.begin(), voxels2.end()); - for (MoleculePool::container_type::size_type i(0); i < voxels1.size(); ++i) + for (MoleculePool::container_type::size_type i(0); i < voxels1.size(); + ++i) { BOOST_CHECK_EQUAL(voxels1.at(i).pid, voxels2.at(i).pid); - BOOST_CHECK_EQUAL(voxels1.at(i).coordinate, voxels2.at(i).coordinate); + BOOST_CHECK_EQUAL(voxels1.at(i).coordinate, + voxels2.at(i).coordinate); } } } diff --git a/ecell4/core/tests/OffLatticeSpace_test.cpp b/ecell4/core/tests/OffLatticeSpace_test.cpp index 40640a5ab..d580ce7f1 100644 --- a/ecell4/core/tests/OffLatticeSpace_test.cpp +++ b/ecell4/core/tests/OffLatticeSpace_test.cpp @@ -1,10 +1,10 @@ #define BOOST_TEST_MODULE "OffLatticeSpace_test" #ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -# include +#include #else -# define BOOST_TEST_NO_LIB -# include +#define BOOST_TEST_NO_LIB +#include #endif #include @@ -17,32 +17,31 @@ using namespace ecell4; struct Fixture { const Real voxel_radius; + const Species base; const Species species; - const ParticleVoxel voxel; + const OffLatticeSpace::coordinate_type coordinate; OffLatticeSpace space; SerialIDGenerator sidgen; - Fixture() : - voxel_radius(2.5e-9), - species(/* serial = */ "SpeciesA", - /* radius = */ 2.5e-9, - /* D = */ 1e-12), - voxel(/* species = */ species, - /* coordinate = */ 3, - /* radius = */ 2.5e-9, - /* D = */ 1e-12), - space(voxel_radius) + Fixture() + : voxel_radius(2.5e-9), base(/* serial = */ "Base", + /* radius = */ 2.5e-9, + /* D = */ 1e-12), + species(/* serial = */ "SpeciesA", + /* radius = */ 2.5e-9, + /* D = */ 1e-12, + /* location = */ "Base"), + coordinate(3), space(voxel_radius, base) { OffLatticeSpace::position_container positions; const Real unit(voxel_radius / sqrt(3.0)); for (int i(0); i < 10; ++i) - positions.push_back( - Real3(unit * i, unit * i, unit * i)); + positions.push_back(Real3(unit * i, unit * i, unit * i)); OffLatticeSpace::coordinate_pair_list_type adjoining_pairs; - for (int i(1); i < 10; ++i ) - adjoining_pairs.push_back( - std::make_pair(i-1, i)); - space = OffLatticeSpace(voxel_radius, positions, adjoining_pairs); + for (int i(1); i < 10; ++i) + adjoining_pairs.push_back(std::make_pair(i - 1, i)); + space = OffLatticeSpace(voxel_radius, base, positions, adjoining_pairs); + space.make_molecular_type(species, "Base"); } }; @@ -58,7 +57,7 @@ BOOST_AUTO_TEST_CASE(CheckVacantSize) BOOST_AUTO_TEST_CASE(OffLatticeSpace_test_molecules) { const ParticleID pid(sidgen()); - space.update_voxel(pid, voxel); + space.update_voxel(pid, species, coordinate); BOOST_CHECK_EQUAL(space.num_molecules(species), 1); } @@ -66,12 +65,12 @@ BOOST_AUTO_TEST_CASE(OffLatticeSpace_test_molecules) BOOST_AUTO_TEST_CASE(OffLatticeSpace_test_voxelspacebase) { const ParticleID pid(sidgen()); - space.update_voxel(pid, voxel); + space.update_voxel(pid, species, coordinate); BOOST_CHECK_EQUAL(space.list_species().size(), 1); BOOST_CHECK_EQUAL(space.num_voxels_exact(species), 1); BOOST_CHECK_EQUAL(space.num_voxels(species), 1); - BOOST_CHECK_EQUAL(space.num_voxels(), 1); + BOOST_CHECK_EQUAL(space.num_voxels(), 10); BOOST_CHECK(space.has_voxel(pid)); BOOST_CHECK(!space.has_voxel(sidgen())); @@ -80,9 +79,9 @@ BOOST_AUTO_TEST_CASE(OffLatticeSpace_test_voxelspacebase) BOOST_CHECK_EQUAL(space.list_voxels(species).size(), 1); BOOST_CHECK_EQUAL(space.list_voxels_exact(species).size(), 1); - BOOST_CHECK_EQUAL(space.list_voxels().at(0).first, pid); - BOOST_CHECK_EQUAL(space.list_voxels(species).at(0).first, pid); - BOOST_CHECK_EQUAL(space.list_voxels_exact(species).at(0).first, pid); + BOOST_CHECK_EQUAL(space.list_voxels().at(0).pid, pid); + BOOST_CHECK_EQUAL(space.list_voxels(species).at(0).pid, pid); + BOOST_CHECK_EQUAL(space.list_voxels_exact(species).at(0).pid, pid); BOOST_CHECK_NO_THROW(space.find_voxel_pool(species)); BOOST_CHECK(space.has_molecule_pool(species)); @@ -93,24 +92,34 @@ BOOST_AUTO_TEST_CASE(OffLatticeSpace_test_voxel) { const ParticleID pid(sidgen()); - BOOST_CHECK(space.update_voxel(pid, voxel)); + BOOST_CHECK(!space.has_voxel(pid)); + BOOST_CHECK(space.update_voxel(pid, species, coordinate)); + + BOOST_CHECK(space.has_voxel(pid)); BOOST_CHECK(space.remove_voxel(pid)); + + BOOST_CHECK(!space.has_voxel(pid)); BOOST_CHECK(!space.remove_voxel(3)); - BOOST_CHECK(space.update_voxel(pid, voxel)); + BOOST_CHECK(!space.has_voxel(pid)); + BOOST_CHECK(space.update_voxel(pid, species, coordinate)); + + BOOST_CHECK(space.has_voxel(pid)); BOOST_CHECK(space.remove_voxel(3)); + + BOOST_CHECK(!space.has_voxel(pid)); BOOST_CHECK(!space.remove_voxel(pid)); } BOOST_AUTO_TEST_CASE(OffLatticeSpace_test_move) { const ParticleID pid(sidgen()); - BOOST_CHECK(space.update_voxel(pid, voxel)); + BOOST_CHECK(space.update_voxel(pid, species, coordinate)); BOOST_CHECK(space.can_move(3, 4)); BOOST_CHECK(space.move(3, 4, 0)); - BOOST_CHECK_EQUAL(space.get_voxel_at(3).first, ParticleID()); - BOOST_CHECK_EQUAL(space.get_voxel_at(4).first, pid); + BOOST_CHECK_EQUAL(space.get_voxel_at(3).pid, ParticleID()); + BOOST_CHECK_EQUAL(space.get_voxel_at(4).pid, pid); BOOST_CHECK(!space.can_move(3, 4)); } @@ -120,16 +129,10 @@ BOOST_AUTO_TEST_CASE(OffLatticeSpace_test_at) BOOST_CHECK_EQUAL(space.size(), 10); const ParticleID pid(sidgen()); - BOOST_CHECK(space.update_voxel(pid, voxel)); + BOOST_CHECK(space.update_voxel(pid, species, coordinate)); BOOST_CHECK_NO_THROW(space.get_voxel_at(3)); - BOOST_CHECK_EQUAL(space.get_voxel_at(3).first, pid); - - BOOST_CHECK_NO_THROW(space.particle_at(3)); - BOOST_CHECK_EQUAL(space.particle_at(3).species(), species); - BOOST_CHECK_EQUAL(space.particle_at(3).position(), space.coordinate2position(3)); - BOOST_CHECK_EQUAL(space.particle_at(3).radius(), 2.5e-9); - BOOST_CHECK_EQUAL(space.particle_at(3).D(), 1e-12); + BOOST_CHECK_EQUAL(space.get_voxel_at(3).pid, pid); } BOOST_AUTO_TEST_CASE(OffLatticeSpace_test_neighbor) diff --git a/ecell4/python_api/spatiocyte.cpp b/ecell4/python_api/spatiocyte.cpp index ba8c7f42e..4adc77b50 100644 --- a/ecell4/python_api/spatiocyte.cpp +++ b/ecell4/python_api/spatiocyte.cpp @@ -1,7 +1,9 @@ #include "python_api.hpp" -#include +#include +#include #include +#include #include #include #include @@ -19,32 +21,28 @@ namespace ecell4 namespace python_api { -static inline -void define_reaction_info(py::module& m) +static inline void define_reaction_info(py::module &m) { using container_type = ReactionInfo::container_type; py::class_(m, "ReactionInfo") - .def(py::init(), - py::arg("t"), py::arg("reactants"), py::arg("products")) + .def(py::init(), + py::arg("t"), py::arg("reactants"), py::arg("products")) .def("t", &ReactionInfo::t) .def("reactants", &ReactionInfo::reactants) .def("products", &ReactionInfo::products) .def(py::pickle( - [](const ReactionInfo& self) - { - return py::make_tuple(self.t(), self.reactants(), self.products()); + [](const ReactionInfo &self) { + return py::make_tuple(self.t(), self.reactants(), + self.products()); }, - [](py::tuple t) - { + [](py::tuple t) { if (t.size() != 3) throw std::runtime_error("Invalid state"); - return ReactionInfo( - t[0].cast(), - t[1].cast(), - t[2].cast() - ); - } - )); + return ReactionInfo(t[0].cast(), + t[1].cast(), + t[2].cast()); + })); py::class_(m, "ReactionInfoItem") .def_readonly("pid", &ReactionInfo::Item::pid) @@ -52,28 +50,28 @@ void define_reaction_info(py::module& m) .def_readonly("voxel", &ReactionInfo::Item::voxel); } -static inline -void define_spatiocyte_factory(py::module& m) +static inline void define_spatiocyte_factory(py::module &m) { py::class_ factory(m, "SpatiocyteFactory"); factory .def(py::init(), - py::arg("voxel_radius") = SpatiocyteFactory::default_voxel_radius()) + py::arg("voxel_radius") = + SpatiocyteFactory::default_voxel_radius()) .def("rng", &SpatiocyteFactory::rng); define_factory_functions(factory); m.attr("Factory") = factory; } -static inline -void define_spatiocyte_simulator(py::module& m) +static inline void define_spatiocyte_simulator(py::module &m) { py::class_, - boost::shared_ptr> simulator(m, "SpatiocyteSimulator"); - simulator - .def(py::init>(), py::arg("w")) - .def(py::init, boost::shared_ptr>(), - py::arg("w"), py::arg("m")) + boost::shared_ptr> + simulator(m, "SpatiocyteSimulator"); + simulator.def(py::init>(), py::arg("w")) + .def(py::init, + boost::shared_ptr>(), + py::arg("w"), py::arg("m")) .def("last_reactions", &SpatiocyteSimulator::last_reactions) .def("set_t", &SpatiocyteSimulator::set_t); define_simulator_functions(simulator); @@ -81,34 +79,40 @@ void define_spatiocyte_simulator(py::module& m) m.attr("Simulator") = simulator; } -static inline -void define_spatiocyte_world(py::module& m) +static inline void define_spatiocyte_world(py::module &m) { - py::class_, - boost::shared_ptr> world(m, "SpatiocyteWorld"); + py::class_, boost::shared_ptr> + world(m, "SpatiocyteWorld"); world - .def(py::init(), - py::arg("edge_lengths") = Real3(1.0, 1.0, 1.0)) - .def(py::init(), - py::arg("edge_lengths"), py::arg("voxel_radius")) - .def(py::init&>(), - py::arg("edge_lengths"), - py::arg("voxel_radius"), - py::arg("rng")) + .def(py::init(), + py::arg("edge_lengths") = Real3(1.0, 1.0, 1.0)) + .def(py::init(), py::arg("edge_lengths"), + py::arg("voxel_radius")) + .def(py::init &>(), + py::arg("edge_lengths"), py::arg("voxel_radius"), py::arg("rng")) .def(py::init(), py::arg("filename")) - .def("new_particle", (boost::optional (SpatiocyteWorld::*)(const Particle&)) &SpatiocyteWorld::new_particle) - .def("new_particle", (boost::optional (SpatiocyteWorld::*)(const Species&, const Real3&)) &SpatiocyteWorld::new_particle) + .def("new_particle", (boost::optional(SpatiocyteWorld::*)( + const Particle &)) & + SpatiocyteWorld::new_particle) + .def("new_particle", (boost::optional(SpatiocyteWorld::*)( + const Species &, const Real3 &)) & + SpatiocyteWorld::new_particle) .def("remove_particle", &SpatiocyteWorld::remove_particle) - .def("list_structure_particles", &SpatiocyteWorld::list_structure_particles) - .def("list_non_structure_particles", &SpatiocyteWorld::list_non_structure_particles) + .def("list_structure_particles", + &SpatiocyteWorld::list_structure_particles) + .def("list_non_structure_particles", + &SpatiocyteWorld::list_non_structure_particles) .def("update_particle", &SpatiocyteWorld::update_particle) .def("add_molecules", - (bool (SpatiocyteWorld::*)(const Species&, const Integer&)) - &SpatiocyteWorld::add_molecules) + (bool (SpatiocyteWorld::*)(const Species &, const Integer &)) & + SpatiocyteWorld::add_molecules) .def("add_molecules", - (bool (SpatiocyteWorld::*)(const Species&, const Integer&, const boost::shared_ptr)) - &SpatiocyteWorld::add_molecules) + (bool (SpatiocyteWorld::*)(const Species &, const Integer &, + const boost::shared_ptr)) & + SpatiocyteWorld::add_molecules) .def("remove_molecules", &SpatiocyteWorld::remove_molecules) .def("voxel_volume", &SpatiocyteWorld::voxel_volume) .def("get_volume", &SpatiocyteWorld::get_volume) @@ -116,14 +120,17 @@ void define_spatiocyte_world(py::module& m) .def("get_species_at", &SpatiocyteWorld::get_species_at) .def("has_particle_at", &SpatiocyteWorld::has_particle_at) .def("set_value", &SpatiocyteWorld::set_value) - .def("new_particle", (boost::optional (SpatiocyteWorld::*)(const Species&, const Voxel&))&SpatiocyteWorld::new_particle) + .def("new_particle", (boost::optional(SpatiocyteWorld::*)( + const Species &, const Voxel &)) & + SpatiocyteWorld::new_particle) .def("new_voxel", - (boost::optional (SpatiocyteWorld::*)(const Species&, const Voxel&))&SpatiocyteWorld::new_particle, - R"pbdoc( + (boost::optional(SpatiocyteWorld::*)(const Species &, + const Voxel &)) & + SpatiocyteWorld::new_particle, + R"pbdoc( .. deprecated::3.0 Use :func:`new_particle` instead. - )pbdoc" - ) + )pbdoc") .def("new_voxel_structure", &SpatiocyteWorld::new_voxel_structure) .def("voxel_radius", &SpatiocyteWorld::voxel_radius) .def("size", &SpatiocyteWorld::size) @@ -145,48 +152,70 @@ void define_spatiocyte_world(py::module& m) Use :func:`has_particle` instead. )pbdoc") .def("rng", &SpatiocyteWorld::rng) - .def_static("calculate_voxel_volume", &SpatiocyteWorld::calculate_voxel_volume) - .def_static("calculate_hcp_lengths", &SpatiocyteWorld::calculate_hcp_lengths) + .def("add_offlattice", + [](SpatiocyteWorld &self, const Species &species, + const OffLattice &offlattice) { + const auto info = self.get_molecule_info(species); + const auto updated = Species(species.serial(), info.radius, + info.D, info.loc, info.dimension); + self.add_space(offlattice.generate_space(updated)); + }) + .def_static("calculate_voxel_volume", + &SpatiocyteWorld::calculate_voxel_volume) + .def_static("calculate_hcp_lengths", + &SpatiocyteWorld::calculate_hcp_lengths) .def_static("calculate_shape", &SpatiocyteWorld::calculate_shape) - .def_static("calculate_volume", &SpatiocyteWorld::calculate_volume); - - m.def("create_spatiocyte_world_cell_list_impl", &create_spatiocyte_world_cell_list_impl_alias); - m.def("create_spatiocyte_world_vector_impl", &create_spatiocyte_world_vector_impl_alias); - m.def("create_spatiocyte_world_square_offlattice_impl", &allocate_spatiocyte_world_square_offlattice_impl); + .def_static("calculate_volume", &SpatiocyteWorld::calculate_volume) + .def("list_neighbors", + [](const SpatiocyteWorld &self, const Voxel &voxel) { + std::vector list; + for (auto i = 0; i < self.num_neighbors(voxel); ++i) + { + list.push_back(self.get_neighbor(voxel, i)); + } + return list; + }); + + m.def("create_spatiocyte_world_cell_list_impl", + &create_spatiocyte_world_cell_list_impl); + m.def("create_spatiocyte_world_vector_impl", + &create_spatiocyte_world_vector_impl); + m.def("create_spatiocyte_world_square_offlattice_impl", + &allocate_spatiocyte_world_square_offlattice_impl); m.attr("World") = world; } -static inline -void define_voxel(py::module& m) +static inline void define_voxel(py::module &m) { py::class_(m, "Voxel") - .def("position", &Voxel::position) #ifndef NDEBUG .def_readonly("coordinate", &Voxel::coordinate) #endif - .def("list_neighbors", - [](const Voxel& self) - { - std::vector list; - for (auto i = 0; i < self.num_neighbors(); ++i) - { - list.push_back(self.get_neighbor(i)); - } - return list; - }); + .def("position", &Voxel::position); } -void setup_spatiocyte_module(py::module& m) +static inline void define_offlattice(py::module &m) +{ + py::class_(m, "OffLattice") + .def(py::init()) + .def(py::init()) + .def("voxel_radius", &OffLattice::voxel_radius) + .def("positions", &OffLattice::positions) + .def("adjoining_pairs", &OffLattice::adjoining_pairs); +} + +void setup_spatiocyte_module(py::module &m) { define_reaction_info(m); + define_offlattice(m); define_spatiocyte_factory(m); define_spatiocyte_simulator(m); define_spatiocyte_world(m); define_voxel(m); } -} - -} +} // namespace python_api +} // namespace ecell4 diff --git a/ecell4/spatiocyte/OffLattice.hpp b/ecell4/spatiocyte/OffLattice.hpp new file mode 100644 index 000000000..31e4d0f9b --- /dev/null +++ b/ecell4/spatiocyte/OffLattice.hpp @@ -0,0 +1,67 @@ +#ifndef ECELL4_SPATIOCYTE_OFFLATTICE_HPP +#define ECELL4_SPATIOCYTE_OFFLATTICE_HPP + +#include +#include + +namespace ecell4 +{ + +namespace spatiocyte { + +class OffLattice { +public: + using positions_type = OffLatticeSpace::position_container; + using adjoining_pairs_type = OffLatticeSpace::coordinate_pair_list_type; + + OffLattice(const Real voxel_radius, const positions_type positions, const adjoining_pairs_type adjoining_pairs) + : voxel_radius_(voxel_radius), positions_(positions), adjoining_pairs_(adjoining_pairs) {} + + OffLattice(const Real voxel_radius, const positions_type positions) + : voxel_radius_(voxel_radius), positions_(positions) + { + constexpr Real epsilon = std::numeric_limits::epsilon(); + + adjoining_pairs_.clear(); + const std::size_t size = positions_.size(); + for (std::size_t i(0); i < size; ++i) + for (std::size_t j(i+1); j < size; ++j) + if (length(positions_[j] - positions_[i]) <= voxel_radius_ + epsilon) + { + adjoining_pairs_.push_back(std::make_pair(i, j)); + } + } + + inline const Real& voxel_radius() const + { + return voxel_radius_; + } + + inline const positions_type& positions() const + { + return positions_; + } + + inline const adjoining_pairs_type& adjoining_pairs() const + { + return adjoining_pairs_; + } + + std::unique_ptr generate_space(const Species& species) const + { + return std::unique_ptr( + new OffLatticeSpace(voxel_radius_, species, positions_, adjoining_pairs_)); + } + +protected: + + Real voxel_radius_; + positions_type positions_; + adjoining_pairs_type adjoining_pairs_; +}; + +} // spatiocyte + +} // ecell4 + +#endif /* ECELL4_SPATIOCYTE_OFFLATTICE_HPP */ diff --git a/ecell4/spatiocyte/OneToManyMap.hpp b/ecell4/spatiocyte/OneToManyMap.hpp index 91e487c87..5badde991 100644 --- a/ecell4/spatiocyte/OneToManyMap.hpp +++ b/ecell4/spatiocyte/OneToManyMap.hpp @@ -1,9 +1,9 @@ #ifndef ECELL4_SPATIOCYTE_INTERFACE_CONTAINER #define ECELL4_SPATIOCYTE_INTERFACE_CONTAINER -#include #include #include +#include namespace ecell4 { @@ -11,13 +11,11 @@ namespace ecell4 namespace spatiocyte { -template -class OneToManyMap -{ +template class OneToManyMap { protected: - typedef typename utils::get_mapper_mf >::type - container_type; + typedef + typename utils::get_mapper_mf>::type container_type; typedef typename container_type::iterator iterator; @@ -41,12 +39,13 @@ class OneToManyMap iterator itr(container_.find(key)); if (itr != container_.end()) - std::copy(values.begin(), values.end(), back_inserter((*itr).second)); + std::copy(values.begin(), values.end(), + back_inserter((*itr).second)); else container_.insert(std::make_pair(key, values)); } - boost::optional&> find(const T& key) const + boost::optional &> find(const T &key) const { const_iterator itr(container_.find(key)); diff --git a/ecell4/spatiocyte/ReactionEvent.cpp b/ecell4/spatiocyte/ReactionEvent.cpp index 74ff999b4..4836fcb5c 100644 --- a/ecell4/spatiocyte/ReactionEvent.cpp +++ b/ecell4/spatiocyte/ReactionEvent.cpp @@ -1,13 +1,16 @@ #include "SpatiocyteEvent.hpp" -namespace ecell4 { +namespace ecell4 +{ -namespace spatiocyte { +namespace spatiocyte +{ /// ZerothOrderReactionEvent ZerothOrderReactionEvent::ZerothOrderReactionEvent( - boost::shared_ptr world, const ReactionRule& rule, const Real& t) + boost::shared_ptr world, const ReactionRule &rule, + const Real &t) : SpatiocyteEvent(t), world_(world), rule_(rule) { time_ = t + draw_dt(); @@ -17,15 +20,16 @@ void ZerothOrderReactionEvent::fire_() { ReactionInfo rinfo(world_->t()); - for (ReactionRule::product_container_type::const_iterator - i(rule_.products().begin()); - i != rule_.products().end(); ++i) + for (const auto &sp : rule_.products()) { - const Species& sp(*i); const MoleculeInfo info(world_->get_molecule_info(sp)); - if (boost::shared_ptr location = world_->find_voxel_pool(Species(info.loc))) + if (const auto space_and_location = + world_->find_space_and_voxel_pool(Species(info.loc))) { + const auto space = space_and_location->first; + const auto location = space_and_location->second; + if (location->size() == 0) { time_ += draw_dt(); @@ -34,14 +38,16 @@ void ZerothOrderReactionEvent::fire_() while (true) { - const Voxel voxel(world_->coordinate2voxel(world_->rng()->uniform_int(0, world_->size()-1))); + const Voxel voxel( + space, world_->rng()->uniform_int(0, space->size() - 1)); if (voxel.get_voxel_pool() != location) { continue; } - if (boost::optional pid = world_->new_particle(sp, voxel)) + if (boost::optional pid = + world_->new_particle(sp, voxel)) { rinfo.add_product(ReactionInfo::Item(*pid, sp, voxel)); break; @@ -60,57 +66,56 @@ Real ZerothOrderReactionEvent::draw_dt() Real dt(inf); if (p != 0.) { - const Real rnd(world_->rng()->uniform(0.,1.)); - dt = - log(1 - rnd) / p; + const Real rnd(world_->rng()->uniform(0., 1.)); + dt = -log(1 - rnd) / p; } return dt; } - /// FirstOrderReactionEvent FirstOrderReactionEvent::FirstOrderReactionEvent( - boost::shared_ptr world, const ReactionRule& rule, const Real& t) + boost::shared_ptr world, const ReactionRule &rule, + const Real &t) : SpatiocyteEvent(t), world_(world), rng_(world->rng()), rule_(rule) { - //assert(rule_.reactants().size() == 1); + // assert(rule_.reactants().size() == 1); time_ = t + draw_dt(); } void FirstOrderReactionEvent::fire_() { const ReactionInfo::Item reactant_item(choice()); - const ReactionRule::product_container_type& products(rule_.products()); + const ReactionRule::product_container_type &products(rule_.products()); switch (products.size()) { - case 0: - { - reactant_item.voxel.clear(); - ReactionInfo rinfo(world_->t()); - rinfo.add_reactant(reactant_item); - push_reaction(std::make_pair(rule_, rinfo)); - } - break; - case 1: - push_reaction(std::make_pair(rule_, - apply_a2b(world_, reactant_item, *(products.begin())))); - break; - case 2: - { - ReactionInfo rinfo(apply_a2bc(world_, reactant_item, - *(products.begin()), (*(++products.begin())))); - if (rinfo.has_occurred()) - push_reaction(std::make_pair(rule_, rinfo)); - } - break; + case 0: { + reactant_item.voxel.clear(); + ReactionInfo rinfo(world_->t()); + rinfo.add_reactant(reactant_item); + push_reaction(std::make_pair(rule_, rinfo)); + } + break; + case 1: + push_reaction(std::make_pair( + rule_, apply_a2b(world_, reactant_item, *(products.begin())))); + break; + case 2: { + ReactionInfo rinfo(apply_a2bc(world_, reactant_item, + *(products.begin()), + (*(++products.begin())))); + if (rinfo.has_occurred()) + push_reaction(std::make_pair(rule_, rinfo)); + } + break; } time_ += draw_dt(); } Real FirstOrderReactionEvent::draw_dt() { - const Species& reactant(*(rule_.reactants().begin())); + const Species &reactant(*(rule_.reactants().begin())); const Integer num_r(world_->num_voxels_exact(reactant)); const Real k(rule_.k()); if (num_r > 0) @@ -120,7 +125,7 @@ Real FirstOrderReactionEvent::draw_dt() if (p != 0.) { const Real rnd(world_->rng()->uniform(0., 1.)); - dt = - log(1 - rnd) / p; + dt = -log(1 - rnd) / p; } return dt; } @@ -130,6 +135,6 @@ Real FirstOrderReactionEvent::draw_dt() } } -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/spatiocyte/SpatiocyteEvent.hpp b/ecell4/spatiocyte/SpatiocyteEvent.hpp index 0df06f1f6..9265853e0 100644 --- a/ecell4/spatiocyte/SpatiocyteEvent.hpp +++ b/ecell4/spatiocyte/SpatiocyteEvent.hpp @@ -1,11 +1,12 @@ #ifndef ECELL4_SPATIOCYTE_EVENT_HPP #define ECELL4_SPATIOCYTE_EVENT_HPP -#include -#include -#include #include "SpatiocyteReactions.hpp" #include "SpatiocyteWorld.hpp" +#include "utils.hpp" +#include +#include +#include namespace ecell4 { @@ -18,15 +19,13 @@ struct SpatiocyteEvent : public Event public: typedef std::pair reaction_type; - SpatiocyteEvent(Real const& time) : Event(time) {} + SpatiocyteEvent(Real const &time) : Event(time) {} virtual ~SpatiocyteEvent() {} - const std::vector& reactions() const - { - return reactions_; - } + const std::vector &reactions() const { return reactions_; } - virtual void fire() { + virtual void fire() + { reactions_.clear(); fire_(); } @@ -34,33 +33,51 @@ struct SpatiocyteEvent : public Event protected: virtual void fire_() = 0; - void push_reaction(const reaction_type& reaction) + void push_reaction(const reaction_type &reaction) { reactions_.push_back(reaction); } std::vector reactions_; - }; +template +const Real calc_dt(const Real R, const Real D); + +template struct StepEvent : SpatiocyteEvent { StepEvent(boost::shared_ptr model, - boost::shared_ptr world, - const Species& species, - const Real& t, - const Real alpha=1.0); - virtual ~StepEvent() {} - - Species const& species() const + boost::shared_ptr world, const Species &species, + const Real &t, const Real alpha = 1.0) + : SpatiocyteEvent(t), model_(model), world_(world), alpha_(alpha) { - return mpool_->species(); + if (const auto space_and_molecule_pool = + world_->find_space_and_molecule_pool(species)) + { + space_ = space_and_molecule_pool->first; + mpool_ = space_and_molecule_pool->second; + } + else + { + throw "MoleculePool is not found"; + } + + const MoleculeInfo minfo(world_->get_molecule_info(species)); + const Real D(minfo.D); + const Real R(world_->voxel_radius()); + + if (D <= 0) + dt_ = inf; + else + dt_ = calc_dt(R, D) * alpha_; + + time_ = t + dt_; } - Real const& alpha() const - { - return alpha_; - } + Species const &species() const { return mpool_->species(); } + + Real const &alpha() const { return alpha_; } void fire_() { @@ -68,96 +85,154 @@ struct StepEvent : SpatiocyteEvent time_ += dt_; } - virtual void walk(const Real& alpha) = 0; + void walk(const Real &alpha) + { + if (alpha < 0 || alpha > 1) + { + return; // INVALID ALPHA VALUE + } + + MoleculePool::container_type voxels; + copy(mpool_->begin(), mpool_->end(), back_inserter(voxels)); + + std::size_t idx(0); + for (const auto &info : voxels) + { + const Voxel voxel(space_, info.coordinate); + + if (voxel.get_voxel_pool() != mpool_) + { + // should skip if a voxel is not the target species. + // when reaction has occured before, a voxel can be changed. + continue; + } + + const Voxel neighbor = + world_->get_neighbor_randomly(voxel); + + if (world_->can_move(voxel, neighbor)) + { + if (world_->rng()->uniform(0, 1) <= alpha) + world_->move(voxel, neighbor, /*candidate=*/idx); + } + else + { + attempt_reaction_(info, neighbor, alpha); + } + + ++idx; + } + } protected: - - void attempt_reaction_( - const SpatiocyteWorld::coordinate_id_pair_type& info, - const Voxel& dst, - const Real& alpha); + void attempt_reaction_(const SpatiocyteWorld::coordinate_id_pair_type &info, + const Voxel &dst, const Real &alpha) + { + const Voxel voxel(space_, info.coordinate); + boost::shared_ptr from_mt(voxel.get_voxel_pool()); + boost::shared_ptr to_mt(dst.get_voxel_pool()); + + const Species &speciesA(from_mt->species()); + const Species &speciesB(to_mt->species()); + + const std::vector rules( + model_->query_reaction_rules(speciesA, speciesB)); + + if (rules.empty()) + { + return; + } + + const Real from_D(world_->get_molecule_info(speciesA).D); + const Real to_D(world_->get_molecule_info(speciesB).D); + const Real factor( + calculate_dimensional_factor(from_mt, from_D, to_mt, to_D, world_)); + const Real rnd(world_->rng()->uniform(0, 1)); + Real accp(0.0); + + for (const auto &rule : rules) + { + const Real k(rule.k()); + const Real P(k * factor * alpha); + accp += P; + if (accp > 1 && k != std::numeric_limits::infinity()) + { + std::cerr << "The total acceptance probability [" << accp + << "] exceeds 1 for '" << speciesA.serial() + << "' and '" << speciesB.serial() << "'." + << std::endl; + } + if (accp >= rnd) + { + ReactionInfo rinfo(apply_second_order_reaction( + world_, rule, + ReactionInfo::Item(info.pid, from_mt->species(), voxel), + ReactionInfo::Item(to_mt->get_particle_id(dst.coordinate), + to_mt->species(), dst))); + if (rinfo.has_occurred()) + { + reaction_type reaction(std::make_pair(rule, rinfo)); + push_reaction(reaction); + } + return; + } + } + } protected: - boost::shared_ptr model_; boost::shared_ptr world_; + boost::weak_ptr space_; boost::shared_ptr mpool_; const Real alpha_; }; -struct StepEvent3D : StepEvent -{ - StepEvent3D(boost::shared_ptr model, - boost::shared_ptr world, - const Species& species, - const Real& t, - const Real alpha=1.0); - - void walk(const Real& alpha); -}; - -struct StepEvent2D : StepEvent -{ - StepEvent2D(boost::shared_ptr model, - boost::shared_ptr world, - const Species& species, - const Real& t, - const Real alpha=1.0); - - void walk(const Real& alpha); - -protected: - - std::vector nids_; // neighbor indexes -}; - struct ZerothOrderReactionEvent : SpatiocyteEvent { - ZerothOrderReactionEvent( - boost::shared_ptr world, const ReactionRule& rule, const Real& t); + ZerothOrderReactionEvent(boost::shared_ptr world, + const ReactionRule &rule, const Real &t); virtual ~ZerothOrderReactionEvent() {} virtual void fire_(); Real draw_dt(); - virtual void interrupt(Real const& t) - { - time_ = t + draw_dt(); - } + virtual void interrupt(Real const &t) { time_ = t + draw_dt(); } protected: - boost::shared_ptr world_; ReactionRule rule_; }; struct FirstOrderReactionEvent : SpatiocyteEvent { - FirstOrderReactionEvent( - boost::shared_ptr world, const ReactionRule& rule, const Real& t); + FirstOrderReactionEvent(boost::shared_ptr world, + const ReactionRule &rule, const Real &t); virtual ~FirstOrderReactionEvent() {} virtual void fire_(); Real draw_dt(); - virtual void interrupt(Real const& t) - { - time_ = t + draw_dt(); - } + virtual void interrupt(Real const &t) { time_ = t + draw_dt(); } protected: - ReactionInfo::Item choice() { - const Species& species(rule_.reactants().at(0)); - boost::shared_ptr mt(world_->find_molecule_pool(species)); - - const Integer i(rng_.lock()->uniform_int(0, mt->size() - 1)); - const SpatiocyteWorld::coordinate_id_pair_type& info(mt->at(i)); - - // TODO: Calling coordinate2voxel() is invalid - return ReactionInfo::Item(info.pid, species, world_->coordinate2voxel(info.coordinate)); + const Species &species(rule_.reactants().at(0)); + if (const auto space_and_molecule_pool = + world_->find_space_and_molecule_pool(species)) + { + const auto space = space_and_molecule_pool->first; + const auto molecule_pool = space_and_molecule_pool->second; + + const auto i = + rng_.lock()->uniform_int(0, molecule_pool->size() - 1); + const auto &info = molecule_pool->at(i); + + return ReactionInfo::Item(info.pid, species, + Voxel(space, info.coordinate)); + } + throw "MoleculePool is not found"; } boost::shared_ptr world_; @@ -165,8 +240,8 @@ struct FirstOrderReactionEvent : SpatiocyteEvent ReactionRule rule_; }; -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_SPATIOCYTE_EVENT_HPP */ diff --git a/ecell4/spatiocyte/SpatiocyteFactory.hpp b/ecell4/spatiocyte/SpatiocyteFactory.hpp index f480db046..6da5ad2de 100644 --- a/ecell4/spatiocyte/SpatiocyteFactory.hpp +++ b/ecell4/spatiocyte/SpatiocyteFactory.hpp @@ -1,13 +1,12 @@ #ifndef ECELL4_LATTICE_LATTICE_FACTORY_HPP #define ECELL4_LATTICE_LATTICE_FACTORY_HPP -#include #include +#include -#include -#include "SpatiocyteWorld.hpp" #include "SpatiocyteSimulator.hpp" - +#include "SpatiocyteWorld.hpp" +#include namespace ecell4 { @@ -15,18 +14,15 @@ namespace ecell4 namespace spatiocyte { -class SpatiocyteFactory: - public SimulatorFactory -{ +class SpatiocyteFactory + : public SimulatorFactory { public: - typedef SimulatorFactory base_type; typedef base_type::world_type world_type; typedef base_type::simulator_type simulator_type; typedef SpatiocyteFactory this_type; public: - SpatiocyteFactory(const Real voxel_radius = default_voxel_radius()) : base_type(), rng_(), voxel_radius_(voxel_radius) { @@ -38,25 +34,22 @@ class SpatiocyteFactory: ; // do nothing } - static inline const Real default_voxel_radius() - { - return 0.0; - } + static inline const Real default_voxel_radius() { return 0.0; } - this_type& rng(const boost::shared_ptr& rng) + this_type &rng(const boost::shared_ptr &rng) { rng_ = rng; return (*this); } - inline this_type* rng_ptr(const boost::shared_ptr& rng) + inline this_type * + rng_ptr(const boost::shared_ptr &rng) { - return &(this->rng(rng)); //XXX: == this + return &(this->rng(rng)); // XXX: == this } protected: - - virtual world_type* create_world(const Real3& edge_lengths) const + virtual world_type *create_world(const Real3 &edge_lengths) const { if (rng_) { @@ -73,13 +66,12 @@ class SpatiocyteFactory: } protected: - boost::shared_ptr rng_; Real voxel_radius_; }; -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_LATTICE_LATTICE_FACTORY_HPP */ diff --git a/ecell4/spatiocyte/SpatiocyteReactions.cpp b/ecell4/spatiocyte/SpatiocyteReactions.cpp index 503774820..9395aed9d 100644 --- a/ecell4/spatiocyte/SpatiocyteReactions.cpp +++ b/ecell4/spatiocyte/SpatiocyteReactions.cpp @@ -9,43 +9,38 @@ namespace spatiocyte // Utilities -inline -const std::string -get_serial(boost::shared_ptr world, - const Voxel& voxel) +inline const std::string get_serial(boost::shared_ptr world, + const Voxel &voxel) { - boost::shared_ptr mtype(voxel.get_voxel_pool()); - return mtype->is_vacant() ? "" : mtype->species().serial(); + return voxel.get_voxel_pool()->species().serial(); } -inline -const std::string -get_location(boost::shared_ptr world, - const Voxel& voxel) +inline const std::string get_location(boost::shared_ptr world, + const Voxel &voxel) { boost::shared_ptr mtype(voxel.get_voxel_pool()); if (mtype->is_vacant()) return ""; - boost::shared_ptr ltype(mtype->location()); - return ltype->is_vacant() ? "" : ltype->species().serial(); + return mtype->location()->species().serial(); } -static inline void -make_product(boost::shared_ptr world, - ReactionInfo& rinfo, - const Species& species, - const Voxel voxel) +static inline void make_product(boost::shared_ptr world, + ReactionInfo &rinfo, const Species &species, + const Voxel voxel) { - if (world->has_species(species) && world->find_voxel_pool(species)->is_structure()) + if (world->has_species(species) && + world->find_voxel_pool(species)->is_structure()) { - if (boost::optional new_pid = world->new_voxel_structure(species, voxel)) + if (boost::optional new_pid = + world->new_voxel_structure(species, voxel)) { rinfo.add_product(ReactionInfo::Item(*new_pid, species, voxel)); } } else { - if (boost::optional new_pid = world->new_particle(species, voxel)) + if (boost::optional new_pid = + world->new_particle(species, voxel)) { rinfo.add_product(ReactionInfo::Item(*new_pid, species, voxel)); } @@ -54,10 +49,9 @@ make_product(boost::shared_ptr world, // Application of reactions -ReactionInfo -apply_a2b(boost::shared_ptr world, - const ReactionInfo::Item& reactant_item, - const Species& product_species) +ReactionInfo apply_a2b(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item, + const Species &product_species) { const Voxel voxel(reactant_item.voxel); const std::string bloc(world->get_molecule_info(product_species).loc); @@ -88,17 +82,18 @@ apply_a2b(boost::shared_ptr world, else { // When B is the location of A, it's enough to remove A - std::pair id_species_pair(world->get_voxel_at(voxel)); - rinfo.add_product(ReactionInfo::Item(id_species_pair.first, - id_species_pair.second, - voxel)); + std::pair id_species_pair( + world->get_voxel_at(voxel)); + rinfo.add_product(ReactionInfo::Item( + id_species_pair.first, id_species_pair.second, voxel)); } } else { // A is NOT on the location of B. // B must be released into a neighbor, which is the location of B - if (boost::optional neighbor = world->check_neighbor(voxel, bloc)) + if (boost::optional neighbor = + world->check_neighbor(voxel, bloc)) { // The neighbor is the location of B. // Place B at the neighbor, and remove A. @@ -112,19 +107,18 @@ apply_a2b(boost::shared_ptr world, return rinfo; } -ReactionInfo apply_a2bc( - boost::shared_ptr world, - const ReactionInfo::Item& reactant_item, - const Species& product_species0, - const Species& product_species1) +ReactionInfo apply_a2bc(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item, + const Species &product_species0, + const Species &product_species1) { // A (pinfo) becomes B and C (product_species0 and product_species1) // At least, one of A and B must be placed at the neighbor. const Voxel voxel(reactant_item.voxel); const std::string bserial(product_species0.serial()), - cserial(product_species1.serial()), - bloc(world->get_molecule_info(product_species0).loc), - cloc(world->get_molecule_info(product_species1).loc); + cserial(product_species1.serial()), + bloc(world->get_molecule_info(product_species0).loc), + cloc(world->get_molecule_info(product_species1).loc); const std::string aserial(get_serial(world, voxel)); const std::string aloc(get_location(world, voxel)); @@ -141,7 +135,7 @@ ReactionInfo apply_a2bc( if (!neighbor) { - //TODO: C cannot be on the neighbor. + // TODO: C cannot be on the neighbor. return rinfo; } @@ -167,10 +161,10 @@ ReactionInfo apply_a2bc( else { // When B is the location of A, it's enough to remove A - std::pair id_species_pair(world->get_voxel_at(voxel)); - rinfo.add_product(ReactionInfo::Item(id_species_pair.first, - id_species_pair.second, - voxel)); + std::pair id_species_pair( + world->get_voxel_at(voxel)); + rinfo.add_product(ReactionInfo::Item( + id_species_pair.first, id_species_pair.second, voxel)); } // Place a new C-molecule at the neighbor @@ -188,7 +182,7 @@ ReactionInfo apply_a2bc( if (!neighbor) { - //TODO: B cannot be on the neighbor. + // TODO: B cannot be on the neighbor. return rinfo; } @@ -217,20 +211,19 @@ ReactionInfo apply_a2bc( else { // When C is the location of A, it's enough to remove A - std::pair id_species_pair(world->get_voxel_at(voxel)); - rinfo.add_product(ReactionInfo::Item(id_species_pair.first, - id_species_pair.second, - voxel)); + std::pair id_species_pair( + world->get_voxel_at(voxel)); + rinfo.add_product(ReactionInfo::Item( + id_species_pair.first, id_species_pair.second, voxel)); } return rinfo; } return rinfo; } -ReactionInfo apply_vanishment( - boost::shared_ptr world, - const ReactionInfo::Item& reactant_item0, - const ReactionInfo::Item& reactant_item1) +ReactionInfo apply_vanishment(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item0, + const ReactionInfo::Item &reactant_item1) { ReactionInfo rinfo(world->t()); rinfo.add_reactant(reactant_item0); @@ -242,11 +235,10 @@ ReactionInfo apply_vanishment( return rinfo; } -ReactionInfo apply_ab2c( - boost::shared_ptr world, - const ReactionInfo::Item& reactant_item0, - const ReactionInfo::Item& reactant_item1, - const Species& product_species) +ReactionInfo apply_ab2c(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item0, + const ReactionInfo::Item &reactant_item1, + const Species &product_species) { const Voxel voxel0(reactant_item0.voxel); const Voxel voxel1(reactant_item1.voxel); @@ -296,14 +288,12 @@ ReactionInfo apply_ab2c( } // For apply_ab2cd -ReactionInfo apply_ab2cd_in_order( - boost::shared_ptr world, - const ReactionInfo::Item& reactant_item0, - const ReactionInfo::Item& reactant_item1, - const Species& product_species0, - const Species& product_species1, - const Voxel& voxel0, - const Voxel& voxel1) +ReactionInfo apply_ab2cd_in_order(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item0, + const ReactionInfo::Item &reactant_item1, + const Species &product_species0, + const Species &product_species1, + const Voxel &voxel0, const Voxel &voxel1) { ReactionInfo rinfo(world->t()); rinfo.add_reactant(reactant_item0); @@ -315,15 +305,14 @@ ReactionInfo apply_ab2cd_in_order( return rinfo; } -ReactionInfo apply_ab2cd( - boost::shared_ptr world, - const ReactionInfo::Item& reactant_item0, - const ReactionInfo::Item& reactant_item1, - const Species& product_species0, - const Species& product_species1) +ReactionInfo apply_ab2cd(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item0, + const ReactionInfo::Item &reactant_item1, + const Species &product_species0, + const Species &product_species1) { - const Voxel& src(reactant_item0.voxel); - const Voxel& dst(reactant_item1.voxel); + const Voxel &src(reactant_item0.voxel); + const Voxel &dst(reactant_item1.voxel); const std::string aserial(get_serial(world, src)); const std::string aloc(get_location(world, src)); @@ -346,7 +335,9 @@ ReactionInfo apply_ab2cd( // Remove B once if B is not the location of D dst.clear(); } - return apply_ab2cd_in_order(world, reactant_item0, reactant_item1, product_species0, product_species1, src, dst); + return apply_ab2cd_in_order(world, reactant_item0, reactant_item1, + product_species0, product_species1, src, + dst); } else { @@ -360,7 +351,9 @@ ReactionInfo apply_ab2cd( // Remove A once if A is not the location of C src.clear(); } - return apply_ab2cd_in_order(world, reactant_item0, reactant_item1, product_species0, product_species1, src, *neighbor); + return apply_ab2cd_in_order(world, reactant_item0, + reactant_item1, product_species0, + product_species1, src, *neighbor); } } } @@ -378,7 +371,9 @@ ReactionInfo apply_ab2cd( // Remove B once if B is not the location of C dst.clear(); } - return apply_ab2cd_in_order(world, reactant_item0, reactant_item1, product_species0, product_species1, dst, src); + return apply_ab2cd_in_order(world, reactant_item0, reactant_item1, + product_species0, product_species1, dst, + src); } else { @@ -392,13 +387,16 @@ ReactionInfo apply_ab2cd( // Remove A once if A is not the location of D src.clear(); } - return apply_ab2cd_in_order(world, reactant_item0, reactant_item1, product_species0, product_species1, *neighbor, src); + return apply_ab2cd_in_order(world, reactant_item0, + reactant_item1, product_species0, + product_species1, *neighbor, src); } } } else if (bserial == cloc || bloc == cloc) { - if (boost::optional neighbor = (world->check_neighbor(dst, dloc))) + if (boost::optional neighbor = + (world->check_neighbor(dst, dloc))) { src.clear(); if (bserial != cloc) @@ -406,7 +404,9 @@ ReactionInfo apply_ab2cd( // Remove B once if B is not the location of C dst.clear(); } - return apply_ab2cd_in_order(world, reactant_item0, reactant_item1, product_species0, product_species1, dst, *neighbor); + return apply_ab2cd_in_order(world, reactant_item0, reactant_item1, + product_species0, product_species1, dst, + *neighbor); } } else if (bserial == dloc || bloc == dloc) @@ -419,34 +419,38 @@ ReactionInfo apply_ab2cd( // remove b once if b is not the location of d dst.clear(); } - return apply_ab2cd_in_order(world, reactant_item0, reactant_item1, product_species0, product_species1, *neighbor, dst); + return apply_ab2cd_in_order(world, reactant_item0, reactant_item1, + product_species0, product_species1, + *neighbor, dst); } } return ReactionInfo(world->t()); } -ReactionInfo apply_second_order_reaction( - boost::shared_ptr world, - const ReactionRule& reaction_rule, - const ReactionInfo::Item& reactant_item0, - const ReactionInfo::Item& reactant_item1) +ReactionInfo +apply_second_order_reaction(boost::shared_ptr world, + const ReactionRule &reaction_rule, + const ReactionInfo::Item &reactant_item0, + const ReactionInfo::Item &reactant_item1) { - const ReactionRule::product_container_type& products(reaction_rule.products()); + const ReactionRule::product_container_type &products( + reaction_rule.products()); switch (products.size()) { - case 0: - return apply_vanishment(world, reactant_item0, reactant_item1); - case 1: - return apply_ab2c(world, reactant_item0, reactant_item1, *(products.begin())); - case 2: - return apply_ab2cd(world, reactant_item0, reactant_item1, - products.at(0), products.at(1)); - default: - return ReactionInfo(world->t()); + case 0: + return apply_vanishment(world, reactant_item0, reactant_item1); + case 1: + return apply_ab2c(world, reactant_item0, reactant_item1, + products.at(0)); + case 2: + return apply_ab2cd(world, reactant_item0, reactant_item1, + products.at(0), products.at(1)); + default: + return ReactionInfo(world->t()); } } -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/spatiocyte/SpatiocyteReactions.hpp b/ecell4/spatiocyte/SpatiocyteReactions.hpp index 82d32bfe5..3415cc7fe 100644 --- a/ecell4/spatiocyte/SpatiocyteReactions.hpp +++ b/ecell4/spatiocyte/SpatiocyteReactions.hpp @@ -1,10 +1,10 @@ #ifndef ECELL4_SPATIOCYTE_REACTIONS_HPP #define ECELL4_SPATIOCYTE_REACTIONS_HPP +#include "Voxel.hpp" #include -#include #include -#include "Voxel.hpp" +#include namespace ecell4 { @@ -12,71 +12,55 @@ namespace ecell4 namespace spatiocyte { -class ReactionInfo -{ +class ReactionInfo { public: - struct Item { - Item(ParticleID pid, const Species& species, const Voxel& voxel) + Item(ParticleID pid, const Species &species, const Voxel &voxel) : pid(pid), species(species), voxel(voxel) { } ParticleID pid; - Species species; - Voxel voxel; + Species species; + Voxel voxel; }; typedef std::vector container_type; public: - ReactionInfo() : t_(0), reactants_(), products_() {} ReactionInfo(const Real t) : t_(t), reactants_(), products_() {} - ReactionInfo( - const Real t, - const container_type& reactants, - const container_type& products) - : t_(t), reactants_(reactants), products_(products) {} - - ReactionInfo(const ReactionInfo& another) - : t_(another.t()), reactants_(another.reactants()), products_(another.products()) {} + ReactionInfo(const Real t, const container_type &reactants, + const container_type &products) + : t_(t), reactants_(reactants), products_(products) + { + } - Real t() const + ReactionInfo(const ReactionInfo &another) + : t_(another.t()), reactants_(another.reactants()), + products_(another.products()) { - return t_; } + Real t() const { return t_; } + bool has_occurred() const { return reactants_.size() > 0 || products_.size() > 0; } - const container_type& reactants() const - { - return reactants_; - } + const container_type &reactants() const { return reactants_; } - void add_reactant(const Item& item) - { - reactants_.push_back(item); - } + void add_reactant(const Item &item) { reactants_.push_back(item); } - const container_type& products() const - { - return products_; - } + const container_type &products() const { return products_; } - void add_product(const Item& item) - { - products_.push_back(item); - } + void add_product(const Item &item) { products_.push_back(item); } protected: - Real t_; container_type reactants_, products_; }; @@ -85,43 +69,38 @@ class ReactionInfo class SpatiocyteWorld; -ReactionInfo apply_a2b( - boost::shared_ptr world, - const ReactionInfo::Item& reactant_item, - const Species& product_species); - -ReactionInfo apply_a2bc( - boost::shared_ptr world, - const ReactionInfo::Item& reactant_item, - const Species& product_species0, - const Species& product_species1); - -ReactionInfo apply_second_order_reaction( - boost::shared_ptr world, - const ReactionRule& reaction_rule, - const ReactionInfo::Item& reactant_item0, - const ReactionInfo::Item& reactant_item1); - -ReactionInfo apply_vanishment( - boost::shared_ptr world, - const ReactionInfo::Item& reactant_item0, - const ReactionInfo::Item& reactant_item1); - -ReactionInfo apply_ab2c( - boost::shared_ptr world, - const ReactionInfo::Item& reactant_item0, - const ReactionInfo::Item& reactant_item1, - const Species& product_species); - -ReactionInfo apply_ab2cd( - boost::shared_ptr world, - const ReactionInfo::Item& reactant_item0, - const ReactionInfo::Item& reactant_item1, - const Species& product_species0, - const Species& product_species1); - -} // spatiocyte - -} // ecell4 +ReactionInfo apply_a2b(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item, + const Species &product_species); + +ReactionInfo apply_a2bc(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item, + const Species &product_species0, + const Species &product_species1); + +ReactionInfo +apply_second_order_reaction(boost::shared_ptr world, + const ReactionRule &reaction_rule, + const ReactionInfo::Item &reactant_item0, + const ReactionInfo::Item &reactant_item1); + +ReactionInfo apply_vanishment(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item0, + const ReactionInfo::Item &reactant_item1); + +ReactionInfo apply_ab2c(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item0, + const ReactionInfo::Item &reactant_item1, + const Species &product_species); + +ReactionInfo apply_ab2cd(boost::shared_ptr world, + const ReactionInfo::Item &reactant_item0, + const ReactionInfo::Item &reactant_item1, + const Species &product_species0, + const Species &product_species1); + +} // namespace spatiocyte + +} // namespace ecell4 #endif /* ECELL4_SPATIOCYTE_REACTIONS_HPP */ diff --git a/ecell4/spatiocyte/SpatiocyteSimulator.cpp b/ecell4/spatiocyte/SpatiocyteSimulator.cpp index d53f854fd..52f1ee2f1 100644 --- a/ecell4/spatiocyte/SpatiocyteSimulator.cpp +++ b/ecell4/spatiocyte/SpatiocyteSimulator.cpp @@ -2,8 +2,8 @@ #include "utils.hpp" #include -#include #include +#include namespace ecell4 { @@ -14,30 +14,23 @@ namespace spatiocyte void SpatiocyteSimulator::initialize() { last_reactions_.clear(); - species_list_.clear(); //XXX:FIXME: Messy patch - + species_list_.clear(); // XXX:FIXME: Messy patch scheduler_.clear(); update_alpha_map(); - const std::vector species(world_->list_species()); - for (std::vector::const_iterator itr(species.begin()); - itr != species.end(); ++itr) + for (const auto &species : world_->list_species()) { - register_events(*itr); + register_events(species); } - const std::vector& rules(model_->reaction_rules()); - for (std::vector::const_iterator i(rules.begin()); - i != rules.end(); ++i) + for (const auto &rule : model_->reaction_rules()) { - const ReactionRule& rr(*i); - if (rr.reactants().size() != 0) + if (rule.reactants().size() != 0) { continue; } - const boost::shared_ptr - zeroth_order_reaction_event( - create_zeroth_order_reaction_event(rr, world_->t())); + const boost::shared_ptr zeroth_order_reaction_event( + create_zeroth_order_reaction_event(rule, world_->t())); scheduler_.add(zeroth_order_reaction_event); } @@ -50,17 +43,17 @@ void SpatiocyteSimulator::update_alpha_map() if (!model_ || !model_->is_static()) return; - const Model::reaction_rule_container_type reaction_rules(model_->reaction_rules()); - for (Model::reaction_rule_container_type::const_iterator itr(reaction_rules.begin()); - itr != reaction_rules.end(); ++itr) + for (const auto &rule : model_->reaction_rules()) { - const ReactionRule::reactant_container_type& reactants((*itr).reactants()); + const ReactionRule::reactant_container_type &reactants( + rule.reactants()); if (reactants.size() != 2) continue; - const Real alpha(calculate_alpha(*itr, world_)); - for (int i(0); i < 2; ++i) { - const Species& sp(reactants.at(i)); + const Real alpha(calculate_alpha(rule, world_)); + for (int i(0); i < 2; ++i) + { + const Species &sp(reactants.at(i)); alpha_map_type::iterator map_itr(alpha_map_.find(sp)); if (map_itr == alpha_map_.end()) alpha_map_.insert(alpha_map_type::value_type(sp, alpha)); @@ -70,34 +63,31 @@ void SpatiocyteSimulator::update_alpha_map() } } -void SpatiocyteSimulator::register_events(const Species& sp) +void SpatiocyteSimulator::register_events(const Species &sp) { - species_list_.push_back(sp); //XXX:FIXME: Messy patch + species_list_.push_back(sp); // XXX:FIXME: Messy patch if (world_->has_molecule_pool(sp)) { - //TODO: Call steps only if sp is assigned not to StructureType. + // TODO: Call steps only if sp is assigned not to StructureType. alpha_map_type::const_iterator itr(alpha_map_.find(sp)); const Real alpha(itr != alpha_map_.end() ? itr->second : 1.0); const boost::shared_ptr step_event( - create_step_event(sp, world_->t(), alpha)); + create_step_event(sp, world_->t(), alpha)); scheduler_.add(step_event); } - std::vector reaction_rules(model_->query_reaction_rules(sp)); - for (std::vector::const_iterator i(reaction_rules.begin()); - i != reaction_rules.end(); ++i) + for (const auto &rule : model_->query_reaction_rules(sp)) { - const ReactionRule& rr(*i); - const boost::shared_ptr - first_order_reaction_event( - create_first_order_reaction_event(rr, world_->t())); + const boost::shared_ptr first_order_reaction_event( + create_first_order_reaction_event(rule, world_->t())); scheduler_.add(first_order_reaction_event); } } -boost::shared_ptr SpatiocyteSimulator::create_step_event( - const Species& species, const Real& t, const Real& alpha) +boost::shared_ptr +SpatiocyteSimulator::create_step_event(const Species &species, const Real &t, + const Real &alpha) { boost::shared_ptr mpool(world_->find_molecule_pool(species)); const Shape::dimension_kind dimension(world_->get_dimension(species)); @@ -105,50 +95,57 @@ boost::shared_ptr SpatiocyteSimulator::create_step_event( if (dimension == Shape::THREE) { return boost::shared_ptr( - new StepEvent3D(model_, world_, species, t, alpha)); + new StepEvent<3>(model_, world_, species, t, alpha)); } else if (dimension == Shape::TWO) { return boost::shared_ptr( - new StepEvent2D(model_, world_, species, t, alpha)); + new StepEvent<2>(model_, world_, species, t, alpha)); } else { - throw NotSupported("The dimension of a structure must be two or three."); + throw NotSupported( + "The dimension of a structure must be two or three."); } } boost::shared_ptr SpatiocyteSimulator::create_zeroth_order_reaction_event( - const ReactionRule& reaction_rule, const Real& t) + const ReactionRule &reaction_rule, const Real &t) { boost::shared_ptr event( - new ZerothOrderReactionEvent(world_, reaction_rule, t)); + new ZerothOrderReactionEvent(world_, reaction_rule, t)); return event; } boost::shared_ptr SpatiocyteSimulator::create_first_order_reaction_event( - const ReactionRule& reaction_rule, const Real& t) + const ReactionRule &reaction_rule, const Real &t) { - boost::shared_ptr event(new FirstOrderReactionEvent( - world_, reaction_rule, t)); + boost::shared_ptr event( + new FirstOrderReactionEvent(world_, reaction_rule, t)); return event; } void SpatiocyteSimulator::finalize() { - scheduler_type::events_range events(scheduler_.events()); - for (scheduler_type::events_range::iterator itr(events.begin()); - itr != events.end(); ++itr) + for (const auto &item : scheduler_.events()) { - const Real queued_time((*itr).second->time() - (*itr).second->dt()); - StepEvent* step_event(dynamic_cast((*itr).second.get())); - if (step_event != NULL && queued_time < t()) + const auto &event(item.second); + const Real queued_time(event->time() - event->dt()); + auto *step3_event(dynamic_cast *>(event.get())); + if (step3_event != NULL && queued_time < t()) { - const Real factor((t() - queued_time) / (*itr).second->dt()); + const Real factor((t() - queued_time) / event->dt()); // assert(factor <= 1); - step_event->walk(step_event->alpha() * factor); + step3_event->walk(step3_event->alpha() * factor); + } + auto *step2_event(dynamic_cast *>(event.get())); + if (step2_event != NULL && queued_time < t()) + { + const Real factor((t() - queued_time) / event->dt()); + // assert(factor <= 1); + step2_event->walk(step2_event->alpha() * factor); } } @@ -161,7 +158,7 @@ void SpatiocyteSimulator::step() dt_ = scheduler_.next_time() - t(); } -bool SpatiocyteSimulator::step(const Real& upto) +bool SpatiocyteSimulator::step(const Real &upto) { if (upto < t()) { @@ -188,42 +185,41 @@ void SpatiocyteSimulator::step_() const Real time(top.second->time()); world_->set_t(time); top.second->fire(); // top.second->time_ is updated in fire() - set_last_event_(boost::const_pointer_cast(top.second)); + set_last_event_( + boost::const_pointer_cast(top.second)); last_reactions_ = last_event_->reactions(); std::vector new_species; - for (std::vector::const_iterator itr(last_reactions().begin()); - itr != last_reactions().end(); ++itr) - for (ReactionInfo::container_type::const_iterator - product((*itr).second.products().begin()); - product != (*itr).second.products().end(); ++product) + for (const auto &reaction : last_reactions()) + { + for (const auto &product : reaction.second.products()) { - const Species& species((*product).species); + const Species &species(product.species); // if (!world_->has_species(species)) - if (std::find(species_list_.begin(), species_list_.end(), species) == species_list_.end()) //XXX:FIXME: Messy patch + if (std::find(species_list_.begin(), species_list_.end(), + species) == + species_list_.end()) // XXX:FIXME: Messy patch new_species.push_back(species); } + } - scheduler_type::events_range events(scheduler_.events()); - for (scheduler_type::events_range::iterator itr(events.begin()); - itr != events.end(); ++itr) + for (const auto &event : scheduler_.events()) { - (*itr).second->interrupt(time); - scheduler_.update(*itr); + event.second->interrupt(time); + scheduler_.update(event); } scheduler_.add(top.second); // update_alpha_map(); // may be performance cost - for (std::vector::const_iterator itr(new_species.begin()); - itr != new_species.end(); ++itr) + for (const auto &species : new_species) { - register_events(*itr); + register_events(species); } num_steps_++; } -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/spatiocyte/SpatiocyteSimulator.hpp b/ecell4/spatiocyte/SpatiocyteSimulator.hpp index 55b8916c1..acf89445e 100644 --- a/ecell4/spatiocyte/SpatiocyteSimulator.hpp +++ b/ecell4/spatiocyte/SpatiocyteSimulator.hpp @@ -1,20 +1,20 @@ #ifndef ECELL4_LATTICE_LATTICE_SIMULATOR_HPP #define ECELL4_LATTICE_LATTICE_SIMULATOR_HPP -#include -#include #include +#include +#include +#include #include +#include #include -#include #include -#include -#include +#include #include -#include "SpatiocyteWorld.hpp" #include "SpatiocyteEvent.hpp" +#include "SpatiocyteWorld.hpp" namespace ecell4 { @@ -22,65 +22,54 @@ namespace ecell4 namespace spatiocyte { -class SpatiocyteSimulator - : public SimulatorBase -{ +class SpatiocyteSimulator : public SimulatorBase { public: - typedef SimulatorBase base_type; typedef SpatiocyteEvent::reaction_type reaction_type; typedef EventSchedulerBase scheduler_type; typedef utils::get_mapper_mf::type alpha_map_type; public: - - SpatiocyteSimulator( - boost::shared_ptr world, - boost::shared_ptr model) + SpatiocyteSimulator(boost::shared_ptr world, + boost::shared_ptr model) : base_type(world, model) { initialize(); } - SpatiocyteSimulator( - boost::shared_ptr world) + SpatiocyteSimulator(boost::shared_ptr world) : base_type(world) { initialize(); } - virtual Real dt() const - { - return dt_; - } + virtual Real dt() const { return dt_; } void initialize(); void finalize(); void step(); - bool step(const Real& upto); + bool step(const Real &upto); - virtual bool check_reaction() const - { - return last_reactions().size() > 0; - } + virtual bool check_reaction() const { return last_reactions().size() > 0; } - const std::vector& last_reactions() const + const std::vector &last_reactions() const { // return last_event_->reactions(); return last_reactions_; } protected: - - boost::shared_ptr create_step_event( - const Species& species, const Real& t, const Real& alpha); - boost::shared_ptr create_zeroth_order_reaction_event( - const ReactionRule& reaction_rule, const Real& t); - boost::shared_ptr create_first_order_reaction_event( - const ReactionRule& reaction_rule, const Real& t); + boost::shared_ptr + create_step_event(const Species &species, const Real &t, const Real &alpha); + boost::shared_ptr + create_zeroth_order_reaction_event(const ReactionRule &reaction_rule, + const Real &t); + boost::shared_ptr + create_first_order_reaction_event(const ReactionRule &reaction_rule, + const Real &t); void step_(); - void register_events(const Species& species); + void register_events(const Species &species); void update_alpha_map(); void set_last_event_(boost::shared_ptr event) @@ -89,8 +78,8 @@ class SpatiocyteSimulator } protected: - - scheduler_type scheduler_; boost::shared_ptr last_event_; + scheduler_type scheduler_; + boost::shared_ptr last_event_; alpha_map_type alpha_map_; std::vector last_reactions_; @@ -100,8 +89,8 @@ class SpatiocyteSimulator Real dt_; }; -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_LATTICE_LATTICE_SIMULATOR_HPP */ diff --git a/ecell4/spatiocyte/SpatiocyteWorld.cpp b/ecell4/spatiocyte/SpatiocyteWorld.cpp index a45e27d9d..b5b414733 100644 --- a/ecell4/spatiocyte/SpatiocyteWorld.cpp +++ b/ecell4/spatiocyte/SpatiocyteWorld.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include "SpatiocyteWorld.hpp" @@ -9,43 +9,53 @@ namespace ecell4 namespace spatiocyte { -void SpatiocyteWorld::add_space(VoxelSpaceBase *space) +void SpatiocyteWorld::add_space(std::unique_ptr uniq_space) { - for (coordinate_type i(0); i < space->size(); ++i) + boost::shared_ptr space(uniq_space.release()); + + for (auto i(0); i < space->size(); ++i) { - const Real3 position(space->coordinate2position(i)); - const coordinate_type nearest(get_root()->position2coordinate(position)); + const Voxel voxel(space, i); + const auto position(voxel.position()); + const Voxel nearest(get_root(), + get_root()->position2coordinate(position)); - for (Integer j(0); j < get_root()->num_neighbors(nearest); ++j) + for (Integer j(0); j < num_neighbors(nearest); ++j) { - const coordinate_type neighbor(get_root()->get_neighbor(nearest, j)); - if (length(get_root()->coordinate2position(neighbor) - position) < voxel_radius() * 2) - interfaces_.add(neighbor, i + size_); + const auto neighbor(get_neighbor(nearest, j)); + if (length(neighbor.position() - position) < voxel_radius() * 2) + { + interfaces_.add(neighbor, voxel); + } } } - for (OneToManyMap::const_iterator itr(interfaces_.begin()); - itr != interfaces_.end(); ++itr) + for (const auto &interface : interfaces_) { - std::vector neighbors; - for (Integer i(0); i < get_root()->num_neighbors((*itr).first); ++i) + const Voxel voxel(interface.first); + + std::vector neighbors; + for (auto i(0); i < num_neighbors(voxel); ++i) { - const coordinate_type neighbor(get_root()->get_neighbor((*itr).first, i)); - if (! interfaces_.find(neighbor)) + const auto neighbor(get_neighbor(voxel, i)); + + if (!interfaces_.find(neighbor)) + { neighbors.push_back(neighbor); + } } - for (std::vector::const_iterator jtr((*itr).second.begin()); - jtr != (*itr).second.end(); ++jtr) - neighbors_.extend(*jtr, neighbors); + for (const auto &adjoining : interface.second) + { + neighbors_.extend(adjoining, neighbors); + } } - spaces_.push_back(space_type(space)); - size_ += space->size(); + spaces_.push_back(space); } -void SpatiocyteWorld::set_value(const Species& sp, const Real value) +void SpatiocyteWorld::set_value(const Species &sp, const Real value) { const Integer num1 = static_cast(value); const Integer num2 = num_molecules_exact(sp); @@ -59,57 +69,56 @@ void SpatiocyteWorld::set_value(const Species& sp, const Real value) } } -std::vector > +std::vector> SpatiocyteWorld::list_structure_particles() const { const std::vector structure_species(list_structure_species()); - typedef std::vector > > tmp_type; + typedef std::vector>> tmp_type; tmp_type tmp_vector(structure_species.size()); Integer num_elements(0); - for (std::vector::const_iterator itr(structure_species.begin()); - itr != structure_species.end(); ++itr) + for (const auto &species : structure_species) { - std::vector > tmp(list_particles(*itr)); + std::vector> tmp( + list_particles(species)); tmp_vector.push_back(tmp); num_elements += tmp.size(); } - std::vector > retval; + std::vector> retval; retval.reserve(num_elements); - for (tmp_type::const_iterator itr(tmp_vector.begin()); - itr != tmp_vector.end(); ++itr) + for (const auto &tmp : tmp_vector) { - retval.insert(retval.end(), (*itr).begin(), (*itr).end()); + retval.insert(retval.end(), tmp.begin(), tmp.end()); } return retval; } -std::vector > +std::vector> SpatiocyteWorld::list_non_structure_particles() const { - const std::vector non_structure_species(list_non_structure_species()); + const std::vector non_structure_species( + list_non_structure_species()); - typedef std::vector > > tmp_type; + typedef std::vector>> tmp_type; tmp_type tmp_vector(non_structure_species.size()); Integer num_elements(0); - for (std::vector::const_iterator itr(non_structure_species.begin()); - itr != non_structure_species.end(); ++itr) + for (const auto &species : non_structure_species) { - std::vector > tmp(list_particles(*itr)); + std::vector> tmp( + list_particles(species)); tmp_vector.push_back(tmp); num_elements += tmp.size(); } - std::vector > retval; + std::vector> retval; retval.reserve(num_elements); - for (tmp_type::const_iterator itr(tmp_vector.begin()); - itr != tmp_vector.end(); ++itr) + for (const auto &tmp : tmp_vector) { - retval.insert(retval.end(), (*itr).begin(), (*itr).end()); + retval.insert(retval.end(), tmp.begin(), tmp.end()); } return retval; @@ -117,62 +126,68 @@ SpatiocyteWorld::list_non_structure_particles() const std::vector SpatiocyteWorld::list_non_structure_species() const { - const std::vector species(list_species()); std::vector retval; - for (std::vector::const_iterator itr(species.begin()); - itr != species.end(); ++itr) + for (const auto &species : list_species()) { - if (!find_voxel_pool(*itr)->is_structure()) - retval.push_back(*itr); + if (!find_voxel_pool(species)->is_structure()) + retval.push_back(species); } return retval; } std::vector SpatiocyteWorld::list_structure_species() const { - const std::vector species(list_species()); std::vector retval; - for (std::vector::const_iterator itr(species.begin()); - itr != species.end(); ++itr) + for (const auto &species : list_species()) { - if (find_voxel_pool(*itr)->is_structure()) - retval.push_back(*itr); + if (find_voxel_pool(species)->is_structure()) + retval.push_back(species); } return retval; } -bool SpatiocyteWorld::add_molecules(const Species& sp, const Integer& num) +bool SpatiocyteWorld::add_molecules(const Species &sp, const Integer &num) { if (num < 0) { - throw std::invalid_argument("The number of molecules must be positive."); + throw std::invalid_argument( + "The number of molecules must be positive."); } const MoleculeInfo info(get_molecule_info(sp)); - Integer count(0); - while (count < num) + if (const auto space_and_location = + find_space_and_voxel_pool(Species(info.loc))) { - const Voxel voxel(coordinate2voxel(rng()->uniform_int(0, size()-1))); + const auto space = space_and_location->first; + const auto location = space_and_location->second; - if (voxel.get_voxel_pool()->species().serial() != info.loc) - { - continue; - } - else if (new_particle(sp, voxel)) + if (location->size() < num) + return false; + + auto count(0); + while (count < num) { - ++count; + const Voxel voxel(space, rng()->uniform_int(0, space->size() - 1)); + + if (voxel.get_voxel_pool() != location) + continue; + + if (new_particle(sp, voxel)) + ++count; } + return true; } - return true; + return false; } -bool SpatiocyteWorld::add_molecules( - const Species& sp, const Integer& num, const boost::shared_ptr shape) +bool SpatiocyteWorld::add_molecules(const Species &sp, const Integer &num, + const boost::shared_ptr shape) { if (num < 0) { - throw std::invalid_argument("The number of molecules must be positive."); + throw std::invalid_argument( + "The number of molecules must be positive."); } const MoleculeInfo info(get_molecule_info(sp)); @@ -195,15 +210,17 @@ bool SpatiocyteWorld::add_molecules( return true; } -Integer SpatiocyteWorld::add_structure( - const Species& sp, const boost::shared_ptr shape) +Integer +SpatiocyteWorld::add_structure(const Species &sp, + const boost::shared_ptr shape) { const MoleculeInfo info(get_molecule_info(sp)); get_root()->make_structure_type(sp, info.loc); if (shape->dimension() != info.dimension) { - throw IllegalArgument("The dimension mismatch occurred between a given species and shape"); + throw IllegalArgument("The dimension mismatch occurred between a given " + "species and shape"); } switch (shape->dimension()) @@ -221,138 +238,189 @@ Integer SpatiocyteWorld::add_structure( } Integer -SpatiocyteWorld::add_structure3( - const Species& sp, - const std::string& location, - const boost::shared_ptr shape -) +SpatiocyteWorld::add_structure3(const Species &sp, const std::string &location, + const boost::shared_ptr shape) { Integer count(0); - for (coordinate_type coord(0); coord < size(); ++coord) + for (const auto &space : spaces_) { - const Voxel voxel(coordinate2voxel(coord)); - - if (!this->is_inside(coord) || shape->is_inside(voxel.position()) > 0) - { - continue; - } - - if (voxel.get_voxel_pool()->species().serial() != location) + for (auto coord(0); coord < space->size(); ++coord) { - throw NotSupported( - "Mismatch in the location. Failed to place '" - + sp.serial() + "' to '" - + voxel.get_voxel_pool()->species().serial() + "'. " - + "'" + location + "' is expected."); - continue; + const Voxel voxel(space, coord); + // should check if coord doesn't point at the boundary. + if (!space->is_inside(coord) || + shape->is_inside(voxel.position()) > 0) + continue; + + if (voxel.get_voxel_pool()->species().serial() != location) + { + throw NotSupported( + "Mismatch in the location. Failed to place '" + + sp.serial() + "' to '" + + voxel.get_voxel_pool()->species().serial() + "'. " + "'" + + location + "' is expected."); + continue; + } + + if (new_voxel_structure(sp, voxel)) + ++count; } - - if (new_voxel_structure(sp, voxel)) - ++count; } return count; } Integer -SpatiocyteWorld::add_structure2( - const Species& sp, - const std::string& location, - const boost::shared_ptr shape -) +SpatiocyteWorld::add_structure2(const Species &sp, const std::string &location, + const boost::shared_ptr shape) { Integer count(0); - for (coordinate_type coord(0); coord < size(); ++coord) + for (const auto &space : spaces_) { - const Voxel voxel(coordinate2voxel(coord)); - if (!this->is_inside(coord) || !is_surface_voxel(voxel, shape)) - { - continue; - } - - if (voxel.get_voxel_pool()->species().serial() != location) + for (auto coord(0); coord < space->size(); ++coord) { - throw NotSupported( - "Mismatch in the location. Failed to place '" - + sp.serial() + "' to '" - + voxel.get_voxel_pool()->species().serial() + "'. " - + "'" + location + "' is expected."); - continue; + const Voxel voxel(space, coord); + // should check if coord doesn't point at the boundary. + if (!space->is_inside(coord) || !is_surface_voxel(voxel, shape)) + continue; + if (voxel.get_voxel_pool()->species().serial() != location) + { + throw NotSupported( + "Mismatch in the location. Failed to place '" + + sp.serial() + "' to '" + + voxel.get_voxel_pool()->species().serial() + "'. " + "'" + + location + "' is expected."); + continue; + } + + if (new_voxel_structure(sp, voxel)) + ++count; } - - if (new_voxel_structure(sp, voxel)) - ++count; } return count; } -bool -SpatiocyteWorld::is_surface_voxel( - const Voxel& voxel, - const boost::shared_ptr shape) const +bool SpatiocyteWorld::is_surface_voxel( + const Voxel &voxel, const boost::shared_ptr shape) const { const Real L(shape->is_inside(voxel.position())); if (L > 0 || L < -2 * voxel_radius()) return false; - for (Integer i(0); i < voxel.num_neighbors(); ++i) - if (shape->is_inside(voxel.get_neighbor(i).position()) > 0) + for (Integer i(0); i < num_neighbors(voxel); ++i) + if (shape->is_inside(get_neighbor(voxel, i).position()) > 0) return true; return false; } -void SpatiocyteWorld::remove_molecules(const Species& sp, const Integer& num) +void SpatiocyteWorld::remove_molecules(const Species &sp, const Integer &num) { if (num < 0) - { - throw std::invalid_argument("The number of molecules must be positive."); - } - - boost::shared_ptr mtype(find_molecule_pool(sp)); - if (mtype->size() < num) { throw std::invalid_argument( - "The number of molecules cannot be negative."); + "The number of molecules must be positive."); } - Integer count(0); - while (count < num) + if (const auto space_and_molecule_pool = find_space_and_molecule_pool(sp)) { - const Integer idx(rng_->uniform_int(0, mtype->size() - 1)); - if (coordinate2voxel(mtype->at(idx).coordinate).clear()) + const auto space = space_and_molecule_pool->first; + const auto molecule_pool = space_and_molecule_pool->second; + + if (molecule_pool->size() < num) + throw std::invalid_argument( + "The number of molecules cannot be negative."); + + auto count(0); + while (count < num) { - ++count; + const auto idx(rng_->uniform_int(0, molecule_pool->size() - 1)); + const Voxel voxel(space, molecule_pool->at(idx).coordinate); + if (voxel.clear()) + { + ++count; + } } } } -boost::optional -SpatiocyteWorld::check_neighbor(const Voxel& voxel, const std::string& loc) +boost::optional SpatiocyteWorld::check_neighbor(const Voxel &voxel, + const std::string &loc) { - const std::size_t num_neighbors(voxel.num_neighbors()); + const std::size_t num(num_neighbors(voxel)); std::vector tmp; - tmp.reserve(num_neighbors); + tmp.reserve(num); - for (unsigned int rnd(0); rnd < num_neighbors; ++rnd) + for (unsigned int rnd(0); rnd < num; ++rnd) { - const Voxel neighbor(voxel.get_neighbor(rnd)); + const Voxel neighbor(get_neighbor(voxel, rnd)); boost::shared_ptr mt(neighbor.get_voxel_pool()); - const std::string serial(mt->is_vacant() ? "" : mt->species().serial()); - if (serial == loc) + if (mt->species().serial() == loc) { tmp.push_back(neighbor); } } + if (const auto neighbors = neighbors_.find(voxel)) + { + for (const auto &neighbor : *neighbors) + { + if (neighbor.get_voxel_pool()->species().serial() == loc) + { + tmp.push_back(neighbor); + } + } + } + if (tmp.size() == 0) { return boost::none; } - return tmp[rng()->uniform_int(0, tmp.size()-1)]; + return tmp[rng()->uniform_int(0, tmp.size() - 1)]; +} + +template <> +const Voxel SpatiocyteWorld::get_neighbor_randomly<3>(const Voxel &voxel) +{ + const auto idx(rng()->uniform_int(0, num_neighbors(voxel) - 1)); + const auto neighbor = get_neighbor(voxel, idx); + + if (const auto neighbors = interfaces_.find(neighbor)) + { + const auto idx(rng()->uniform_int(0, neighbors->size() - 1)); + return neighbors->at(idx); + } + + return neighbor; +} + +template <> +const Voxel SpatiocyteWorld::get_neighbor_randomly<2>(const Voxel &voxel) +{ + std::vector neighbors; + for (Integer idx = 0; idx < num_neighbors(voxel); ++idx) + { + const Voxel neighbor = get_neighbor(voxel, idx); + if (get_dimension(neighbor.get_voxel_pool()->species()) > Shape::TWO) + { + continue; + } + neighbors.push_back(neighbor); + } + + const Integer idx(rng()->uniform_int(0, neighbors.size() - 1)); + const auto neighbor = neighbors.at(idx); + + if (const auto neighbors = interfaces_.find(neighbor)) + { + const auto idx(rng()->uniform_int(0, neighbors->size() - 1)); + return neighbors->at(idx); + } + + return neighbor; } -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/spatiocyte/SpatiocyteWorld.hpp b/ecell4/spatiocyte/SpatiocyteWorld.hpp index 74244e431..38d05436f 100644 --- a/ecell4/spatiocyte/SpatiocyteWorld.hpp +++ b/ecell4/spatiocyte/SpatiocyteWorld.hpp @@ -1,25 +1,26 @@ #ifndef ECELL4_LATTICE_LATTICE_WORLD_HPP #define ECELL4_LATTICE_LATTICE_WORLD_HPP -#include -#include #include #include +#include +#include +#include #include #include +#include #include -#include #include #include -#include #include -#include +#include #include +#include #include "OneToManyMap.hpp" -#include "Voxel.hpp" #include "SpatiocyteReactions.hpp" +#include "Voxel.hpp" namespace ecell4 { @@ -29,116 +30,120 @@ namespace spatiocyte struct MoleculeInfo { - const Real radius; - const Real D; - const std::string loc; - const Shape::dimension_kind dimension; + Real radius; + Real D; + std::string loc; + Shape::dimension_kind dimension; }; -class SpatiocyteWorld - : public WorldInterface +class SpatiocyteWorld : public WorldInterface { public: - typedef LatticeSpaceVectorImpl default_root_type; typedef VoxelSpaceBase::coordinate_id_pair_type coordinate_id_pair_type; - typedef VoxelSpaceBase::coordinate_type coordinate_type; typedef boost::shared_ptr space_type; typedef std::vector space_container_type; public: - /* * Constructors */ - SpatiocyteWorld(const Real3& edge_lengths, const Real& voxel_radius, - const boost::shared_ptr& rng) + SpatiocyteWorld(const Real3 &edge_lengths, const Real &voxel_radius, + const boost::shared_ptr &rng) : rng_(rng) { - spaces_.push_back(space_type(new default_root_type(edge_lengths, voxel_radius))); + spaces_.push_back( + space_type(new default_root_type(edge_lengths, voxel_radius))); size_ = get_root()->size(); } - SpatiocyteWorld(const Real3& edge_lengths, const Real& voxel_radius) + SpatiocyteWorld(const Real3 &edge_lengths, const Real &voxel_radius) { - spaces_.push_back(space_type(new default_root_type(edge_lengths, voxel_radius))); + spaces_.push_back( + space_type(new default_root_type(edge_lengths, voxel_radius))); rng_ = boost::shared_ptr( new GSLRandomNumberGenerator()); (*rng_).seed(); size_ = get_root()->size(); } - SpatiocyteWorld(const Real3& edge_lengths = Real3(1, 1, 1)) + SpatiocyteWorld(const Real3 &edge_lengths = Real3(1, 1, 1)) { // XXX: sloppy default - spaces_.push_back(space_type(new default_root_type(edge_lengths, edge_lengths[0] / 100))); + spaces_.push_back(space_type( + new default_root_type(edge_lengths, edge_lengths[0] / 100))); size_ = get_root()->size(); - rng_ = boost::shared_ptr(new GSLRandomNumberGenerator()); + rng_ = boost::shared_ptr( + new GSLRandomNumberGenerator()); (*rng_).seed(); } SpatiocyteWorld(const std::string filename) { // XXX: sloppy default - spaces_.push_back(space_type(new default_root_type(Real3(1, 1, 1), 1 / 100))); + spaces_.push_back( + space_type(new default_root_type(Real3(1, 1, 1), 1 / 100))); rng_ = boost::shared_ptr( new GSLRandomNumberGenerator()); this->load(filename); } - SpatiocyteWorld(VoxelSpaceBase* space, const boost::shared_ptr& rng) + SpatiocyteWorld(VoxelSpaceBase *space, + const boost::shared_ptr &rng) : rng_(rng) { spaces_.push_back(space_type(space)); size_ = get_root()->size(); } - void add_space(VoxelSpaceBase *space); + void add_space(std::unique_ptr space); const Real t() const { Real time(0.0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - time = std::max(time, (*itr)->t()); + time = std::max(time, space->t()); } return time; } - void set_t(const Real& t) + void set_t(const Real &t) { - for (space_container_type::iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (auto &space : spaces_) { - (*itr)->set_t(t); + space->set_t(t); } } - void save(const std::string& filename) const + void save(const std::string &filename) const { #ifdef WITH_HDF5 - boost::scoped_ptr fout(new H5::H5File(filename.c_str(), H5F_ACC_TRUNC)); + boost::scoped_ptr fout( + new H5::H5File(filename.c_str(), H5F_ACC_TRUNC)); rng_->save(fout.get()); sidgen_.save(fout.get()); - boost::scoped_ptr group(new H5::Group(fout->createGroup("LatticeSpace"))); + boost::scoped_ptr group( + new H5::Group(fout->createGroup("LatticeSpace"))); get_root()->save_hdf5(group.get()); // TODO - extras::save_version_information(fout.get(), std::string("ecell4-spatiocyte-") + std::string(VERSION_INFO)); + extras::save_version_information(fout.get(), + std::string("ecell4-spatiocyte-") + + std::string(VERSION_INFO)); #else throw NotSupported( "This method requires HDF5. The HDF5 support is turned off."); #endif } - void load(const std::string& filename) + void load(const std::string &filename) { #ifdef WITH_HDF5 - boost::scoped_ptr - fin(new H5::H5File(filename.c_str(), H5F_ACC_RDONLY)); + boost::scoped_ptr fin( + new H5::H5File(filename.c_str(), H5F_ACC_RDONLY)); const std::string required = "ecell4-spatiocyte-0.0"; try @@ -148,11 +153,12 @@ class SpatiocyteWorld { std::stringstream ss; ss << "The version of the given file [" << version - << "] is too old. [" << required << "] or later is required."; + << "] is too old. [" << required + << "] or later is required."; throw NotSupported(ss.str()); } } - catch(H5::GroupIException not_found_error) + catch (H5::GroupIException not_found_error) { throw NotFound("No version information was found."); } @@ -180,100 +186,58 @@ class SpatiocyteWorld bool has_species(const Species &sp) const { - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - if ((*itr)->has_species(sp)) + if (space->has_species(sp)) return true; } return false; } - Integer num_molecules(const Species& sp) const + Integer num_molecules(const Species &sp) const { Integer total(0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - total += (*itr)->num_molecules(sp); + total += space->num_molecules(sp); } return total; } - Integer num_molecules_exact(const Species& sp) const + Integer num_molecules_exact(const Species &sp) const { Integer total(0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - total += (*itr)->num_molecules_exact(sp); + total += space->num_molecules_exact(sp); } return total; } - Real get_value(const Species& sp) const + Real get_value(const Species &sp) const { - Real value(0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - value += (*itr)->get_value(sp); - } - return value; + return static_cast(num_molecules(sp)); } - Real get_value_exact(const Species& sp) const + Real get_value_exact(const Species &sp) const { - Real value(0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - value += (*itr)->get_value_exact(sp); - } - return value; + return static_cast(num_molecules_exact(sp)); } - const Real3& edge_lengths() const - { - return get_root()->edge_lengths(); - } + const Real3 &edge_lengths() const { return get_root()->edge_lengths(); } - Integer num_particles() const - { - Integer total(0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - total += (*itr)->num_particles(); - } - return total; - } + Integer num_particles() const { return num_voxels(); } - Integer num_particles(const Species& sp) const - { - Integer total(0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - total += (*itr)->num_particles(sp); - } - return total; - } + Integer num_particles(const Species &sp) const { return num_voxels(sp); } - Integer num_particles_exact(const Species& sp) const + Integer num_particles_exact(const Species &sp) const { - Integer total(0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - total += (*itr)->num_particles_exact(sp); - } - return total; + return num_voxels_exact(sp); } - boost::optional get_voxel(const ParticleID& pid) const + boost::optional get_voxel(const ParticleID &pid) const { - for (const auto& space : spaces_) + for (const auto &space : spaces_) { if (const auto coordinate = space->get_coordinate(pid)) return Voxel(space, *coordinate); @@ -281,112 +245,74 @@ class SpatiocyteWorld return boost::none; } - bool has_particle(const ParticleID& pid) const - { - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - if ((*itr)->has_particle(pid)) - return true; - } - return false; - } + bool has_particle(const ParticleID &pid) const { return has_voxel(pid); } // Suggests: Rename to 'find_particle' - std::pair get_particle(const ParticleID& pid) const + std::pair get_particle(const ParticleID &pid) const { - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - if ((*itr)->has_particle(pid)) - return (*itr)->get_particle(pid); + if (const auto &view = space->find_voxel(pid)) + { + return std::make_pair(pid, gen_particle_from(space, *view)); + } } throw "No particle corresponding to a given ParticleID is found."; } - std::vector > list_particles() const + std::vector> list_particles() const { - std::vector > list; - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - std::vector > particles((*itr)->list_particles()); - list.insert(list.end(), particles.begin(), particles.end()); - } - return list; + return list_particles_private( + [](const space_type &space) { return space->list_voxels(); }); } - std::vector > list_particles(const Species& sp) const + std::vector> + list_particles(const Species &sp) const { - std::vector > list; - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - std::vector > particles((*itr)->list_particles(sp)); - list.insert(list.end(), particles.begin(), particles.end()); - } - - return list; + return list_particles_private( + [&sp](const space_type &space) { return space->list_voxels(sp); }); } - std::vector > list_particles_exact(const Species& sp) const + std::vector> + list_particles_exact(const Species &sp) const { - std::vector > list; - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - std::vector > particles( - (*itr)->list_particles_exact(sp)); - list.insert(list.end(), particles.begin(), particles.end()); - } - return list; + return list_particles_private([&sp](const space_type &space) { + return space->list_voxels_exact(sp); + }); } - std::vector > list_structure_particles() const; - std::vector > list_non_structure_particles() const; + std::vector> + list_structure_particles() const; + std::vector> + list_non_structure_particles() const; - Real voxel_radius() const - { - return get_root()->voxel_radius(); - } + Real voxel_radius() const { return get_root()->voxel_radius(); } - Real voxel_volume() const - { - return get_root()->voxel_volume(); - } + Real voxel_volume() const { return get_root()->voxel_volume(); } - Real get_volume(const Species& sp) const + Real get_volume(const Species &sp) const { - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - if ((*itr)->has_species(sp) && (*itr)->find_molecule_pool(sp)->is_structure()) - return (*itr)->get_volume(sp); + if (space->has_species(sp) && + space->find_molecule_pool(sp)->is_structure()) + return space->get_volume(sp); } return 0.0; } - const Real volume() const - { - return get_root()->volume(); - } + const Real volume() const { return get_root()->volume(); } - Real unit_area() const - { - return get_root()->unit_area(); - } + Real unit_area() const { return get_root()->unit_area(); } // TODO - boost::shared_ptr vacant() const { - return get_root()->vacant(); - } + boost::shared_ptr vacant() const { return get_root()->vacant(); } - bool has_voxel(const ParticleID& pid) const + bool has_voxel(const ParticleID &pid) const { - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - if ((*itr)->has_voxel(pid)) + if (space->has_voxel(pid)) return true; } return false; @@ -395,183 +321,201 @@ class SpatiocyteWorld Integer num_voxels() const { Integer total(0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - total += (*itr)->num_voxels(); + total += space->num_voxels(); } return total; } - Integer num_voxels(const Species& sp) const + Integer num_voxels(const Species &sp) const { Integer total(0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - total += (*itr)->num_voxels(sp); + total += space->num_voxels(sp); } return total; } - Integer num_voxels_exact(const Species& sp) const + Integer num_voxels_exact(const Species &sp) const { Integer total(0); - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - total += (*itr)->num_voxels_exact(sp); + total += space->num_voxels_exact(sp); } return total; } - std::vector > list_voxels() const + std::vector> list_voxels() const { - std::vector > list; - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - std::vector > voxels((*itr)->list_voxels()); - list.insert(list.end(), voxels.begin(), voxels.end()); - } - return list; + return list_voxels_private( + [](const space_type &space) { return space->list_voxels(); }); } - std::vector > list_voxels(const Species& sp) const + std::vector> list_voxels(const Species &sp) const { - std::vector > list; - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - std::vector > voxels((*itr)->list_voxels(sp)); - list.insert(list.end(), voxels.begin(), voxels.end()); - } - return list; + return list_voxels_private( + [&sp](const space_type &space) { return space->list_voxels(sp); }); } - std::vector > list_voxels_exact(const Species& sp) const + std::vector> list_voxels_exact(const Species &sp) const { - std::vector > list; - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - std::vector > voxels( - (*itr)->list_voxels_exact(sp)); - list.insert(list.end(), voxels.begin(), voxels.end()); - } - return list; + return list_voxels_private([&sp](const space_type &space) { + return space->list_voxels_exact(sp); + }); } - Species get_species_at(const Voxel& voxel) const + Species get_species_at(const Voxel &voxel) const { return voxel.get_voxel_pool()->species(); } - bool has_particle_at(const Voxel& voxel) const + bool has_particle_at(const Voxel &voxel) const { return !voxel.get_voxel_pool()->is_vacant(); } - std::pair get_voxel_at(const Voxel& voxel) const + std::pair get_voxel_at(const Voxel &voxel) const { - std::pair id_voxel_pair( - voxel.space.lock()->get_voxel_at(voxel.coordinate)); - return std::make_pair(id_voxel_pair.first, id_voxel_pair.second.species); + const auto view(voxel.space.lock()->get_voxel_at(voxel.coordinate)); + return std::make_pair(view.pid, view.species); } - boost::shared_ptr find_voxel_pool(const Species& species) + boost::shared_ptr find_voxel_pool(const Species &species) { - for (space_container_type::iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - if ((*itr)->has_species(species)) - return (*itr)->find_voxel_pool(species); + if (space->has_species(species)) + return space->find_voxel_pool(species); } // create VoxelPool TODO return get_root()->find_voxel_pool(species); // throw "No VoxelPool corresponding to a given Species is found"; } - boost::shared_ptr find_voxel_pool(const Species& species) const + boost::shared_ptr + find_voxel_pool(const Species &species) const { - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - if ((*itr)->has_species(species)) - return (*itr)->find_voxel_pool(species); + if (space->has_species(species)) + return space->find_voxel_pool(species); } throw "No VoxelPool corresponding to a given Species is found"; } - bool has_molecule_pool(const Species& species) const + boost::optional>> + find_space_and_voxel_pool(const Species &species) const { - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - if ((*itr)->has_molecule_pool(species)) + if (space->has_species(species)) + { + const auto voxel_pool = space->find_voxel_pool(species); + return std::pair>( + space, voxel_pool); + } + } + return boost::none; + } + + bool has_molecule_pool(const Species &species) const + { + for (const auto &space : spaces_) + { + if (space->has_molecule_pool(species)) return true; } return false; } - boost::shared_ptr find_molecule_pool(const Species& species) + boost::shared_ptr find_molecule_pool(const Species &species) { - for (space_container_type::iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - if ((*itr)->has_molecule_pool(species)) - return (*itr)->find_molecule_pool(species); + if (space->has_molecule_pool(species)) + return space->find_molecule_pool(species); } throw "No MoleculePool corresponding to a given Species is found"; } - boost::shared_ptr find_molecule_pool(const Species& species) const + boost::shared_ptr + find_molecule_pool(const Species &species) const { - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - if ((*itr)->has_molecule_pool(species)) - return (*itr)->find_molecule_pool(species); + if (space->has_molecule_pool(species)) + return space->find_molecule_pool(species); } throw "No MoleculePool corresponding to a given Species is found"; } + boost::optional>> + find_space_and_molecule_pool(const Species &species) const + { + for (const auto &space : spaces_) + { + if (space->has_molecule_pool(species)) + { + const auto molecule_pool(space->find_molecule_pool(species)); + return std::pair>( + space, molecule_pool); + } + } + return boost::none; + } + /* * Coordinate Transformation */ - Voxel get_voxel_nearby(const Real3& pos) const + Voxel get_voxel_nearby(const Real3 &pos) const { return Voxel(get_root(), get_root()->position2coordinate(pos)); } /* - * ParticleVoxel Manipulation + * Voxel Manipulation */ - bool update_voxel(const ParticleID& pid, ParticleVoxel v) + bool update_voxel(const ParticleID &pid, const Species species, + const Voxel voxel) { - for (space_container_type::iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + const MoleculeInfo minfo(get_molecule_info(species)); + + const auto target_space = voxel.space.lock(); + for (const auto &space : spaces_) { - if ((*itr)->has_voxel(pid)) - return (*itr)->update_voxel(pid, v); + if (space->has_voxel(pid)) + { + if (space != target_space) + { + space->remove_voxel(pid); + } + return target_space->update_voxel(pid, species, + voxel.coordinate); + } } - return get_space(v.coordinate)->update_voxel(pid, v); + if (!target_space->has_species(species)) + { + target_space->make_molecular_type(species, minfo.loc); + } + return target_space->update_voxel(pid, species, voxel.coordinate); } - bool remove_voxel(const ParticleID& pid) + bool remove_voxel(const ParticleID &pid) { - for (space_container_type::iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - if ((*itr)->has_voxel(pid)) - return (*itr)->remove_voxel(pid); + if (space->has_voxel(pid)) + return space->remove_voxel(pid); } return false; } // Deprecated - bool can_move(const Voxel& src, const Voxel& dst) const + bool can_move(const Voxel &src, const Voxel &dst) const { if (!(src.space < dst.space) && !(dst.space < src.space)) return src.space.lock()->can_move(src.coordinate, dst.coordinate); @@ -580,40 +524,48 @@ class SpatiocyteWorld } // Deprecated - bool move(const Voxel& src, const Voxel& dst, const std::size_t candidate=0) + bool move(const Voxel &src, const Voxel &dst, + const std::size_t candidate = 0) { if (!(src.space < dst.space) && !(dst.space < src.space)) - return src.space.lock()->move(src.coordinate, dst.coordinate, candidate); + return src.space.lock()->move(src.coordinate, dst.coordinate, + candidate); return false; - } - const Integer size() const - { - return size_; - } + const Integer size() const { return size_; } - const Integer3 shape() const - { - return get_root()->shape(); - } + const Integer3 shape() const { return get_root()->shape(); } /* * SpatiocyteWorld API */ + const MoleculeInfo get_molecule_info(const Species &sp) const + { + const auto itr = molecule_info_cache_.find(sp); + if (itr != molecule_info_cache_.end()) + { + return itr->second; + } + throw NotFound("MoleculeInfo not found"); + } + /** * draw attributes of species and return it as a molecule info. * @param sp a species * @return info a molecule info */ - const MoleculeInfo get_molecule_info(const Species& sp) + const MoleculeInfo get_molecule_info(const Species &sp) { - boost::optional diffusion_coef; - boost::optional radius; - boost::optional location; - Shape::dimension_kind dimension = Shape::THREE; // The default dimension is 3 + // Default + MoleculeInfo info = { + /* radius = */ voxel_radius(), + /* D = */ 0.0, + /* loc = */ "", + /* dimension = */ Shape::THREE, + }; const auto itr = molecule_info_cache_.find(sp); if (itr != molecule_info_cache_.end()) @@ -621,10 +573,7 @@ class SpatiocyteWorld // return itr->second; // TODO: the below code is only for warning. // In the future, the value should be returned immediately. - diffusion_coef = itr->second.D; - radius = itr->second.radius; - location = itr->second.loc; - dimension = itr->second.dimension; + info = itr->second; } else if (const auto model = lock_model()) { @@ -632,76 +581,72 @@ class SpatiocyteWorld if (species_from_model.has_attribute("D")) { - diffusion_coef = species_from_model.get_attribute_as("D"); + info.D = species_from_model.get_attribute_as("D"); } if (species_from_model.has_attribute("radius")) { - radius = species_from_model.get_attribute_as("radius"); + info.radius = + species_from_model.get_attribute_as("radius"); } if (species_from_model.has_attribute("location")) { - location = species_from_model.get_attribute_as("location"); + info.loc = species_from_model.get_attribute_as( + "location"); } - dimension = extras::get_dimension_from_model(sp, model); + info.dimension = extras::get_dimension_from_model(sp, model); } if (sp.has_attribute("D")) { const auto new_value = sp.get_attribute_as("D"); - if (diffusion_coef && *diffusion_coef != new_value) + if (info.D != new_value) { warning("D"); - diffusion_coef = new_value; + info.D = new_value; } } if (sp.has_attribute("radius")) { const auto new_value = sp.get_attribute_as("radius"); - if (radius && *radius != new_value) + if (info.radius != new_value) { warning("radius"); - radius = new_value; + info.radius = new_value; } } if (sp.has_attribute("location")) { const auto new_value = sp.get_attribute_as("location"); - if (location && *location != new_value) + if (info.loc != new_value) { warning("location"); - location = new_value; + info.loc = new_value; } } - if (diffusion_coef == boost::none) { - diffusion_coef = 0.0; - } - - if (radius == boost::none) { - radius = voxel_radius(); - } - - if (location == boost::none) { - location = ""; - } - - const MoleculeInfo info = {*radius, *diffusion_coef, *location, dimension}; - molecule_info_cache_.insert(molecule_info_cache_t::value_type(sp, info)); + molecule_info_cache_.insert( + molecule_info_cache_t::value_type(sp, info)); return info; } - static inline void - warning(const std::string attribute) + static inline void warning(const std::string attribute) { - std::cerr << "Warning: A given species has an attribute \"" << attribute << "\""; - std::cerr << ", but its value differs from that of the bound Model or the value previously given." << std::endl; - std::cerr << " Giving the different value from a species attribute are deprecated." << std::endl; - std::cerr << " An attribute of a given species will be ignored in the future." << std::endl; + std::cerr << "Warning: A given species has an attribute \"" << attribute + << "\""; + std::cerr << ", but its value differs from that of the bound Model or " + "the value previously given." + << std::endl; + std::cerr << " Giving the different value from a species " + "attribute are deprecated." + << std::endl; + std::cerr << " An attribute of a given species will be ignored " + "in the future." + << std::endl; } // bool has_species_exact(const Species &sp) const @@ -709,8 +654,7 @@ class SpatiocyteWorld // return get_root()->has_species_exact(sp); // } - void set_value(const Species& sp, const Real value); - + void set_value(const Species &sp, const Real value); /** * create and add a new particle @@ -718,8 +662,7 @@ class SpatiocyteWorld * @return a pair of a pair of pid (a particle id) and p (a particle) * and bool (if it's succeeded or not) */ - boost::optional - new_particle(const Particle& p) + boost::optional new_particle(const Particle &p) { // ParticleID pid(sidgen_()); // const bool is_succeeded(update_particle(pid, p)); @@ -736,40 +679,27 @@ class SpatiocyteWorld return boost::none; } - boost::optional - new_particle(const Species& sp, const Real3& pos) + boost::optional new_particle(const Species &sp, + const Real3 &pos) { const MoleculeInfo info(get_molecule_info(sp)); return new_particle(Particle(sp, pos, info.radius, info.D)); } - bool remove_particle(const ParticleID& pid) - { - for (space_container_type::iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) - { - if ((*itr)->has_particle(pid)) - return (*itr)->remove_particle(pid); - } - return false; - } + bool remove_particle(const ParticleID &pid) { return remove_voxel(pid); } - bool update_particle(const ParticleID& pid, const Particle& p) + bool update_particle(const ParticleID &pid, const Particle &p) { const MoleculeInfo minfo(get_molecule_info(p.species())); - return update_voxel(pid, - ParticleVoxel(p.species(), - get_voxel_nearby(p.position()).coordinate, - p.radius(), p.D(), minfo.loc)); + return update_voxel(pid, p.species(), get_voxel_nearby(p.position())); } std::vector list_species() const { std::vector list; - for (space_container_type::const_iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + for (const auto &space : spaces_) { - std::vector species((*itr)->list_species()); + std::vector species(space->list_species()); list.insert(list.end(), species.begin(), species.end()); } return list; @@ -777,15 +707,15 @@ class SpatiocyteWorld std::vector list_non_structure_species() const; std::vector list_structure_species() const; - // std::vector list_coords(const Species& sp) const; - boost::optional new_particle(const Species& sp, const Voxel& voxel) + boost::optional new_particle(const Species &sp, + const Voxel &voxel) { boost::shared_ptr space(voxel.space.lock()); if (!space->has_species(sp)) { const MoleculeInfo minfo(get_molecule_info(sp)); - space->make_molecular_type(sp, minfo.radius, minfo.D, minfo.loc); + space->make_molecular_type(sp, minfo.loc); } ParticleID pid(sidgen_()); @@ -796,14 +726,14 @@ class SpatiocyteWorld return boost::none; } - boost::optional - new_voxel_structure(const Species& sp, const Voxel& voxel) + boost::optional new_voxel_structure(const Species &sp, + const Voxel &voxel) { boost::shared_ptr space(voxel.space.lock()); if (!space->has_species(sp)) { const MoleculeInfo minfo(get_molecule_info(sp)); - space->make_molecular_type(sp, minfo.radius, minfo.D, minfo.loc); + space->make_structure_type(sp, minfo.loc); } ParticleID pid; @@ -814,25 +744,36 @@ class SpatiocyteWorld return boost::none; } - bool add_molecules(const Species& sp, const Integer& num); - bool add_molecules(const Species& sp, const Integer& num, const boost::shared_ptr shape); - Integer add_structure(const Species& sp, const boost::shared_ptr shape); + bool add_molecules(const Species &sp, const Integer &num); + bool add_molecules(const Species &sp, const Integer &num, + const boost::shared_ptr shape); + Integer add_structure(const Species &sp, + const boost::shared_ptr shape); - void remove_molecules(const Species& sp, const Integer& num); + void remove_molecules(const Species &sp, const Integer &num); // void remove_molecules_exact(const Species& sp, const Integer& num); - boost::optional - check_neighbor(const Voxel& voxel, const std::string& loc); - - // bool update_molecule(coordinate_type at, Species species); + boost::optional check_neighbor(const Voxel &voxel, + const std::string &loc); - const Species& draw_species(const Species& pttrn) const; + const Integer num_neighbors(const Voxel &voxel) const + { + return voxel.space.lock()->num_neighbors(voxel.coordinate); + } - boost::shared_ptr rng() + const Voxel get_neighbor(const Voxel &voxel, Integer nrand) const { - return rng_; + return Voxel(voxel.space, + voxel.space.lock()->get_neighbor(voxel.coordinate, nrand)); } + template + const Voxel get_neighbor_randomly(const Voxel &voxel); + + const Species &draw_species(const Species &pttrn) const; + + boost::shared_ptr rng() const { return rng_; } + void bind_to(boost::shared_ptr model) { if (boost::shared_ptr bound_model = model_.lock()) @@ -840,7 +781,7 @@ class SpatiocyteWorld if (bound_model.get() != model.get()) { std::cerr << "Warning: Model already bound to SpatiocyteWorld" - << std::endl; + << std::endl; } } @@ -852,13 +793,22 @@ class SpatiocyteWorld const auto bound = model_.lock(); if (!bound) { - std::cerr << "Warning: Manipulating SpatiocyteWorld without binding Model is deprecated." << std::endl; - std::cerr << " In the future, calling this function before binding Model will throw an exception." << std::endl; + std::cerr << "Warning: Manipulating SpatiocyteWorld without " + "binding Model is deprecated." + << std::endl; + std::cerr << " In the future, calling this function before " + "binding Model will throw an exception." + << std::endl; } return bound; } - Shape::dimension_kind get_dimension(const Species& species) + Shape::dimension_kind get_dimension(const Species &species) + { + return get_molecule_info(species).dimension; + } + + Shape::dimension_kind get_dimension(const Species &species) const { return get_molecule_info(species).dimension; } @@ -876,105 +826,130 @@ class SpatiocyteWorld return VoxelSpaceBase::calculate_hcp_lengths(voxel_radius); } - static inline Integer3 calculate_shape(const Real3& edge_lengths, const Real& voxel_radius) + static inline Integer3 calculate_shape(const Real3 &edge_lengths, + const Real &voxel_radius) { - return VoxelSpaceBase::calculate_shape(edge_lengths, voxel_radius, true); + return VoxelSpaceBase::calculate_shape(edge_lengths, voxel_radius, + true); } - static inline Real calculate_volume(const Real3& edge_lengths, const Real& voxel_radius) + static inline Real calculate_volume(const Real3 &edge_lengths, + const Real &voxel_radius) { - return VoxelSpaceBase::calculate_volume(edge_lengths, voxel_radius, true); + return VoxelSpaceBase::calculate_volume(edge_lengths, voxel_radius, + true); } protected: + space_type get_root() const { return spaces_.at(0); } - bool is_inside(const coordinate_type& coord) const - { - return get_root()->is_inside(coord); - } + Integer add_structure2(const Species &sp, const std::string &location, + const boost::shared_ptr shape); + Integer add_structure3(const Species &sp, const std::string &location, + const boost::shared_ptr shape); + bool is_surface_voxel(const Voxel &voxel, + const boost::shared_ptr shape) const; - space_type get_root() const + Particle gen_particle_from(const space_type &space, + const VoxelView &view) const { - return spaces_.at(0); + const auto species = view.species; + + const auto position = space->coordinate2position(view.voxel); + const auto minfo_iter = molecule_info_cache_.find(species); + if (minfo_iter != molecule_info_cache_.end()) + { + const auto &minfo = minfo_iter->second; + return Particle(species, position, minfo.radius, minfo.D, + minfo.loc); + } + else + { + return Particle(species, position, 0.0, 0.0, ""); + } } - space_type get_space(coordinate_type& coordinate) +private: + template + std::vector map_voxels(ListFn list_f, Fn f) const { - for (space_container_type::iterator itr(spaces_.begin()); - itr != spaces_.end(); ++itr) + std::vector list; + for (const auto &space : spaces_) { - if (coordinate < (*itr)->size()) - return *itr; - - coordinate -= (*itr)->size(); + const auto voxels(list_f(space)); + list.reserve(list.size() + voxels.size()); + for (const auto &item : voxels) + { + list.push_back(f(space, item)); + } } - return space_type(); + return list; } - Integer add_structure2(const Species& sp, const std::string& location, const boost::shared_ptr shape); - Integer add_structure3(const Species& sp, const std::string& location, const boost::shared_ptr shape); - bool is_surface_voxel(const Voxel& voxel, const boost::shared_ptr shape) const; - -public: + template + std::vector> + list_particles_private(ListFn list_fn) const + { + return map_voxels>( + list_fn, [this](const space_type &space, const VoxelView &view) { + return std::make_pair(view.pid, gen_particle_from(space, view)); + }); + } - // TODO: Calling this function is invalid, and this should be removed. - Voxel coordinate2voxel(const coordinate_type& coordinate) + template + std::vector> list_voxels_private(ListFn list_fn) const { - coordinate_type coord(coordinate); - return Voxel(get_space(coord), coord); + return map_voxels>( + list_fn, [this](const space_type &space, const VoxelView &view) { + return ParticleBase(view.pid, view.species, + Voxel(space, view.voxel)); + }); } protected: - - typedef utils::get_mapper_mf::type molecule_info_cache_t; + typedef utils::get_mapper_mf::type + molecule_info_cache_t; std::size_t size_; space_container_type spaces_; - OneToManyMap interfaces_; - OneToManyMap neighbors_; + OneToManyMap interfaces_; + OneToManyMap neighbors_; boost::shared_ptr rng_; SerialIDGenerator sidgen_; boost::weak_ptr model_; molecule_info_cache_t molecule_info_cache_; -}; +}; // namespace spatiocyte -inline -SpatiocyteWorld* -create_spatiocyte_world_cell_list_impl( - const Real3& edge_lengths, - const Real& voxel_radius, - const Integer3& matrix_sizes, - const boost::shared_ptr& rng) +inline SpatiocyteWorld *create_spatiocyte_world_cell_list_impl( + const Real3 &edge_lengths, const Real &voxel_radius, + const Integer3 &matrix_sizes, + const boost::shared_ptr &rng) { return new SpatiocyteWorld( - new LatticeSpaceCellListImpl(edge_lengths, voxel_radius, matrix_sizes), rng); + new LatticeSpaceCellListImpl(edge_lengths, voxel_radius, matrix_sizes), + rng); } -inline -SpatiocyteWorld* -create_spatiocyte_world_vector_impl( - const Real3& edge_lengths, - const Real& voxel_radius, - const boost::shared_ptr& rng) +inline SpatiocyteWorld *create_spatiocyte_world_vector_impl( + const Real3 &edge_lengths, const Real &voxel_radius, + const boost::shared_ptr &rng) { return new SpatiocyteWorld( new LatticeSpaceVectorImpl(edge_lengths, voxel_radius), rng); } -inline -SpatiocyteWorld* -allocate_spatiocyte_world_square_offlattice_impl( - const Real edge_length, - const Real& voxel_radius, - const boost::shared_ptr& rng) +inline SpatiocyteWorld *allocate_spatiocyte_world_square_offlattice_impl( + const Real edge_length, const Species &species, const Real &voxel_radius, + const boost::shared_ptr &rng) { OffLatticeSpace::position_container positions; OffLatticeSpace::coordinate_pair_list_type adjoining_pairs; - // const std::size_t num_row(int((edge_length - (2 + sqrt(3)) * voxel_radius) / + // const std::size_t num_row(int((edge_length - (2 + sqrt(3)) * + // voxel_radius) / // (2 * sqrt(3) * voxel_radius)) + 1); const std::size_t num_row(int(edge_length / (2 * sqrt(3) * voxel_radius))); const std::size_t num_col(int(edge_length / (2 * voxel_radius))); @@ -983,12 +958,12 @@ allocate_spatiocyte_world_square_offlattice_impl( for (std::size_t col(0); col < num_col; ++col) { // 2 * (row * num_col + col) - positions.push_back( - Real3(2*col, 2*row*sqrt(3), 0) * voxel_radius); + positions.push_back(Real3(2 * col, 2 * row * sqrt(3), 0) * + voxel_radius); // 2 * (row * num_col + col + 1) - positions.push_back( - Real3(2*col, (2*row+1)*sqrt(3), 0) * voxel_radius); + positions.push_back(Real3(2 * col, (2 * row + 1) * sqrt(3), 0) * + voxel_radius); const int index(2 * (row * num_col + col)); @@ -999,42 +974,24 @@ allocate_spatiocyte_world_square_offlattice_impl( const int bottom(2 * (next_row * num_col + col)); const int right_bottom(2 * (next_row * num_col + next_col)); - adjoining_pairs.push_back(std::make_pair(index, index+1)); - adjoining_pairs.push_back(std::make_pair(index, right)); - adjoining_pairs.push_back(std::make_pair(index+1, right)); - adjoining_pairs.push_back(std::make_pair(index+1, right+1)); - adjoining_pairs.push_back(std::make_pair(index+1, bottom)); - adjoining_pairs.push_back(std::make_pair(index+1, right_bottom)); + adjoining_pairs.push_back(std::make_pair(index, index + 1)); + adjoining_pairs.push_back(std::make_pair(index, right)); + adjoining_pairs.push_back(std::make_pair(index + 1, right)); + adjoining_pairs.push_back(std::make_pair(index + 1, right + 1)); + adjoining_pairs.push_back(std::make_pair(index + 1, bottom)); + adjoining_pairs.push_back(std::make_pair(index + 1, right_bottom)); } - OffLatticeSpace *space = new OffLatticeSpace(voxel_radius, positions, adjoining_pairs); - space->set_lengths(Real3(2*num_col, 2*sqrt(3)*num_row, 2) * voxel_radius); + OffLatticeSpace *space = + new OffLatticeSpace(voxel_radius, species, positions, adjoining_pairs); + space->set_lengths(Real3(2 * num_col, 2 * sqrt(3) * num_row, 2) * + voxel_radius); return new SpatiocyteWorld(space, rng); } -/** - * Alias functions for Cython - */ - -inline SpatiocyteWorld* create_spatiocyte_world_cell_list_impl_alias( - const Real3& edge_lengths, const Real& voxel_radius, - const Integer3& matrix_sizes, - const boost::shared_ptr& rng) -{ - return create_spatiocyte_world_cell_list_impl( - edge_lengths, voxel_radius, matrix_sizes, rng); -} - -inline SpatiocyteWorld* create_spatiocyte_world_vector_impl_alias( - const Real3& edge_lengths, const Real& voxel_radius, - const boost::shared_ptr& rng) -{ - return create_spatiocyte_world_vector_impl(edge_lengths, voxel_radius, rng); -} - -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_LATTICE_LATTICE_WORLD_HPP */ diff --git a/ecell4/spatiocyte/StepEvent.cpp b/ecell4/spatiocyte/StepEvent.cpp index 2df09a359..686896bce 100644 --- a/ecell4/spatiocyte/StepEvent.cpp +++ b/ecell4/spatiocyte/StepEvent.cpp @@ -1,5 +1,4 @@ #include "SpatiocyteEvent.hpp" -#include "utils.hpp" namespace ecell4 { @@ -7,215 +6,18 @@ namespace ecell4 namespace spatiocyte { -StepEvent::StepEvent(boost::shared_ptr model, boost::shared_ptr world, - const Species& species, const Real& t, const Real alpha) - : SpatiocyteEvent(t), - model_(model), - world_(world), - mpool_(world_->find_molecule_pool(species)), - alpha_(alpha) +template <> +const Real calc_dt<3>(const Real R, const Real D) { - time_ = t; + return 2 * R * R / 3 / D; } -StepEvent3D::StepEvent3D(boost::shared_ptr model, - boost::shared_ptr world, - const Species& species, - const Real& t, - const Real alpha) - : StepEvent(model, world, species, t, alpha) +template <> +const Real calc_dt<2>(const Real R, const Real D) { - const MoleculeInfo minfo(world_->get_molecule_info(species)); - const Real D(minfo.D); - const Real R(world_->voxel_radius()); - - if (D <= 0) - dt_ = inf; - else - dt_ = 2 * R * R / 3 / D * alpha_; - - time_ = t + dt_; -} - -void StepEvent3D::walk(const Real& alpha) -{ - if (alpha < 0 || alpha > 1) - { - return; // INVALID ALPHA VALUE - } - - const boost::shared_ptr& rng(world_->rng()); - MoleculePool::container_type voxels; - copy(mpool_->begin(), mpool_->end(), back_inserter(voxels)); - - std::size_t idx(0); - for (MoleculePool::container_type::iterator itr(voxels.begin()); - itr != voxels.end(); ++itr) - { - const SpatiocyteWorld::coordinate_id_pair_type& info(*itr); - const Voxel voxel(world_->coordinate2voxel(info.coordinate)); - const Integer rnd(rng->uniform_int(0, voxel.num_neighbors()-1)); - - if (voxel.get_voxel_pool() != mpool_) - { - // should skip if a voxel is not the target species. - // when reaction has occured before, a voxel can be changed. - continue; - } - - const Voxel neighbor(voxel.get_neighbor(rnd)); - - if (world_->can_move(voxel, neighbor)) - { - if (rng->uniform(0,1) <= alpha) - world_->move(voxel, neighbor, /*candidate=*/idx); - } - else - { - attempt_reaction_(info, neighbor, alpha); - } - - ++idx; - } -} - -StepEvent2D::StepEvent2D(boost::shared_ptr model, - boost::shared_ptr world, - const Species& species, - const Real& t, - const Real alpha) - : StepEvent(model, world, species, t, alpha) -{ - const MoleculeInfo minfo(world_->get_molecule_info(species)); - const Real D(minfo.D); - const Real R(world_->voxel_radius()); - - if (D <= 0) - dt_ = inf; - else - dt_ = R * R / D * alpha_; - - time_ = t + dt_; - - nids_.clear(); - for (unsigned int i(0); i < 12; ++i) - nids_.push_back(i); -} - -void StepEvent2D::walk(const Real& alpha) -{ - if (alpha < 0 || alpha > 1) - { - return; // INVALID ALPHA VALUE - } - - const boost::shared_ptr& rng(world_->rng()); - MoleculePool::container_type voxels; - copy(mpool_->begin(), mpool_->end(), back_inserter(voxels)); - - std::size_t idx(0); - for (MoleculePool::container_type::iterator itr(voxels.begin()); - itr != voxels.end(); ++itr) - { - const SpatiocyteWorld::coordinate_id_pair_type& info(*itr); - - // TODO: Calling coordinate2voxel is invalid - const Voxel voxel(world_->coordinate2voxel(info.coordinate)); - - if (voxel.get_voxel_pool() != mpool_) - { - // should skip if a voxel is not the target species. - // when reaction has occured before, a voxel can be changed. - continue; - } - - const std::size_t num_neighbors(voxel.num_neighbors()); - - ecell4::shuffle(*(rng.get()), nids_); - for (std::vector::const_iterator itr(nids_.begin()); - itr != nids_.end(); ++itr) - { - if (*itr >= num_neighbors) - continue; - - const Voxel neighbor(voxel.get_neighbor(*itr)); - boost::shared_ptr target(neighbor.get_voxel_pool()); - - if (world_->get_dimension(target->species()) > Shape::TWO) - continue; - - if (world_->can_move(voxel, neighbor)) - { - if (rng->uniform(0,1) <= alpha) - world_->move(voxel, neighbor, /*candidate=*/idx); - } - else - { - attempt_reaction_(info, neighbor, alpha); - } - break; - } - ++idx; - } -} - -void StepEvent::attempt_reaction_( - const SpatiocyteWorld::coordinate_id_pair_type& info, - const Voxel& dst, - const Real& alpha) -{ - // TODO: Calling coordiante2voxel is invalid - const Voxel voxel(world_->coordinate2voxel(info.coordinate)); - boost::shared_ptr from_mt(voxel.get_voxel_pool()); - boost::shared_ptr to_mt(dst.get_voxel_pool()); - - if (to_mt->is_vacant()) - { - return; - } - - const Species& speciesA(from_mt->species()); - const Species& speciesB(to_mt->species()); - - const std::vector rules(model_->query_reaction_rules(speciesA, speciesB)); - - if (rules.empty()) - { - return; - } - - const Real factor(calculate_dimensional_factor(from_mt, to_mt, world_)); - const Real rnd(world_->rng()->uniform(0,1)); - Real accp(0.0); - - for (std::vector::const_iterator itr(rules.begin()); itr != rules.end(); ++itr) - { - const Real k((*itr).k()); - const Real P(k * factor * alpha); - accp += P; - if (accp > 1 && k != std::numeric_limits::infinity()) - { - std::cerr << "The total acceptance probability [" << accp - << "] exceeds 1 for '" << speciesA.serial() - << "' and '" << speciesB.serial() << "'." << std::endl; - } - if (accp >= rnd) - { - ReactionInfo rinfo(apply_second_order_reaction( - world_, *itr, - ReactionInfo::Item(info.pid, from_mt->species(), voxel), - ReactionInfo::Item(to_mt->get_particle_id(dst.coordinate), - to_mt->species(), dst))); - if (rinfo.has_occurred()) - { - reaction_type reaction(std::make_pair(*itr, rinfo)); - push_reaction(reaction); - } - return; - } - } + return R * R / D; } -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/spatiocyte/Voxel.hpp b/ecell4/spatiocyte/Voxel.hpp index 1d8946e26..e4ad04602 100644 --- a/ecell4/spatiocyte/Voxel.hpp +++ b/ecell4/spatiocyte/Voxel.hpp @@ -1,9 +1,10 @@ #ifndef ECELL4_SPATIOCYTE_VOXEL_HPP #define ECELL4_SPATIOCYTE_VOXEL_HPP -#include -#include #include +#include +#include +#include namespace ecell4 { @@ -11,9 +12,11 @@ namespace ecell4 namespace spatiocyte { +class SpatiocyteWorld; + struct Voxel { - typedef Integer coordinate_type; + typedef VoxelSpaceBase::coordinate_type coordinate_type; Voxel(boost::weak_ptr space, coordinate_type coordinate) : space(space), coordinate(coordinate) @@ -24,35 +27,39 @@ struct Voxel coordinate_type coordinate; public: - const Real3 position() const { return space.lock()->coordinate2position(coordinate); } - bool clear() const - { - return space.lock()->remove_voxel(coordinate); - } + bool clear() const { return space.lock()->remove_voxel(coordinate); } boost::shared_ptr get_voxel_pool() const { return space.lock()->get_voxel_pool_at(coordinate); } - Integer num_neighbors() const + bool operator==(const Voxel &rhs) const noexcept { - return space.lock()->num_neighbors(coordinate); + return space.lock() == rhs.space.lock() && coordinate == rhs.coordinate; } +}; + +} // namespace spatiocyte + +} // namespace ecell4 - Voxel get_neighbor(Integer nrand) const +ECELL4_DEFINE_HASH_BEGIN() +template <> +struct hash +{ + std::size_t operator()(const ecell4::spatiocyte::Voxel &val) const { - return Voxel(space, space.lock()->get_neighbor(coordinate, nrand)); + auto ptr = val.space.lock().get(); + return hash()(ptr) ^ + static_cast(val.coordinate); } }; - -} - -} +ECELL4_DEFINE_HASH_END() #endif diff --git a/ecell4/spatiocyte/tests/SpatiocyteSimulator_test.cpp b/ecell4/spatiocyte/tests/SpatiocyteSimulator_test.cpp index 9d8ebca75..31ff84ff7 100644 --- a/ecell4/spatiocyte/tests/SpatiocyteSimulator_test.cpp +++ b/ecell4/spatiocyte/tests/SpatiocyteSimulator_test.cpp @@ -1,16 +1,16 @@ #define BOOST_TEST_MODULE "SpatiocyteSimulator_test" #ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -# include +#include #else -# define BOOST_TEST_NO_LIB -# include +#define BOOST_TEST_NO_LIB +#include #endif #include -#include #include "../SpatiocyteSimulator.hpp" +#include #include using namespace ecell4; @@ -26,18 +26,17 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_constructor) const Real D(1e-12), radius(2.5e-9); - ecell4::Species sp1("A", radius, D), - sp2("B", radius, D), + ecell4::Species sp1("A", radius, D), sp2("B", radius, D), sp3("C", radius, D); boost::shared_ptr model(new NetworkModel()); (*model).add_species_attribute(sp1); (*model).add_species_attribute(sp2); (*model).add_species_attribute(sp3); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); SpatiocyteSimulator sim(world, model); } @@ -55,10 +54,10 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_hdf5_save) boost::shared_ptr model(new NetworkModel()); (*model).add_species_attribute(sp); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); world->add_molecules(sp, N); BOOST_ASSERT(world->num_molecules(sp) == N); @@ -78,12 +77,13 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_step_with_single_particle) boost::shared_ptr model(new NetworkModel()); (*model).add_species_attribute(sp); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); - BOOST_CHECK(world->new_particle(sp, world->get_voxel_nearby(Real3(1.0e-8, 1.0e-8, 1.0e-8)))); + BOOST_CHECK(world->new_particle( + sp, world->get_voxel_nearby(Real3(1.0e-8, 1.0e-8, 1.0e-8)))); SpatiocyteSimulator sim(world, model); @@ -108,10 +108,10 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_step_with_single_species) boost::shared_ptr model(new NetworkModel()); (*model).add_species_attribute(sp); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); world->add_molecules(sp, N / 2); @@ -139,10 +139,10 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_save_step_with_single_species) boost::shared_ptr model(new NetworkModel()); (*model).add_species_attribute(sp); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); SpatiocyteSimulator sim(world, model); @@ -170,10 +170,10 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_save_step_with_periodic) boost::shared_ptr model(new NetworkModel()); (*model).add_species_attribute(sp); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); SpatiocyteSimulator sim(world, model); @@ -194,21 +194,20 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_unimolecular_reaction) const Real3 edge_lengths(L, L, L); const Real voxel_radius(2.5e-9); const Real radius(1.25e-9); - const ecell4::Species sp1("A", radius, 1.0e-12), - sp2("B", radius, 1.1e-12), - sp3("C", 2.5e-9, 1.2e-12); + const ecell4::Species sp1("A", radius, 1.0e-12), sp2("B", radius, 1.1e-12), + sp3("C", 2.5e-9, 1.2e-12); boost::shared_ptr model(new NetworkModel()); model->add_species_attribute(sp1); model->add_species_attribute(sp2); model->add_species_attribute(sp3); - model->add_reaction_rule(create_unimolecular_reaction_rule(sp1,sp3,1e6)); + model->add_reaction_rule(create_unimolecular_reaction_rule(sp1, sp3, 1e6)); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); SpatiocyteSimulator sim(world, model); @@ -230,21 +229,21 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_binding_reaction) const Real3 edge_lengths(L, L, L); const Real voxel_radius(2.5e-9); const Real radius(1.25e-9); - const ecell4::Species sp1("A", radius, 1.0e-12), - sp2("B", radius, 1.1e-12), - sp3("C", 2.5e-9, 1.2e-12); + const ecell4::Species sp1("A", radius, 1.0e-12), sp2("B", radius, 1.1e-12), + sp3("C", 2.5e-9, 1.2e-12); boost::shared_ptr model(new NetworkModel()); model->add_species_attribute(sp1); model->add_species_attribute(sp2); model->add_species_attribute(sp3); - model->add_reaction_rule(create_binding_reaction_rule(sp1,sp2,sp3,1e-20)); + model->add_reaction_rule( + create_binding_reaction_rule(sp1, sp2, sp3, 1e-20)); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); SpatiocyteSimulator sim(world, model); @@ -268,21 +267,21 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_unbinding_reaction) const Real3 edge_lengths(L, L, L); const Real voxel_radius(2.5e-9); const Real radius(1.25e-9); - const ecell4::Species sp1("A", radius, 1.0e-12), - sp2("B", radius, 1.1e-12), - sp3("C", 2.5e-9, 1.2e-12); + const ecell4::Species sp1("A", radius, 1.0e-12), sp2("B", radius, 1.1e-12), + sp3("C", 2.5e-9, 1.2e-12); boost::shared_ptr model(new NetworkModel()); model->add_species_attribute(sp1); model->add_species_attribute(sp2); model->add_species_attribute(sp3); - model->add_reaction_rule(create_unbinding_reaction_rule(sp1,sp2,sp3,1e5)); + model->add_reaction_rule( + create_unbinding_reaction_rule(sp1, sp2, sp3, 1e5)); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); SpatiocyteSimulator sim(world, model); @@ -310,12 +309,12 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_degradation_reaction) boost::shared_ptr model(new NetworkModel()); model->add_species_attribute(sp1); - model->add_reaction_rule(create_degradation_reaction_rule(sp1,1e5)); + model->add_reaction_rule(create_degradation_reaction_rule(sp1, 1e5)); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); SpatiocyteSimulator sim(world, model); @@ -342,17 +341,17 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_finalize) boost::shared_ptr model(new NetworkModel()); (*model).add_species_attribute(sp); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); SpatiocyteSimulator sim(world, model); world->add_molecules(sp, N); sim.initialize(); - while(sim.step(0.311111111)) + while (sim.step(0.311111111)) ; sim.finalize(); @@ -371,18 +370,22 @@ BOOST_AUTO_TEST_CASE(SpatiocyteSimulator_test_shape) boost::shared_ptr model(new NetworkModel()); model->add_species_attribute(membrane); model->add_species_attribute(sp); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); + boost::shared_ptr rng( + new GSLRandomNumberGenerator()); boost::shared_ptr world( - new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); + new SpatiocyteWorld(edge_lengths, voxel_radius, rng)); SpatiocyteSimulator sim(world, model); - boost::shared_ptr sphere(new Sphere(Real3(L/2, L/2, L/2), L*1/3)); + boost::shared_ptr sphere( + new Sphere(Real3(L / 2, L / 2, L / 2), L * 1 / 3)); BOOST_CHECK(world->add_structure(membrane, sphere) > 0); - BOOST_CHECK(!world->new_particle(Particle(sp, Real3(L/2, L/2, L*5/6), 2.5e-9, 1e-12))); // This should fail - BOOST_CHECK(world->new_particle(Particle(sp, Real3(L/2, L/2, L*5/6 - voxel_radius), 2.5e-9, 1e-12))); + BOOST_CHECK( + !world->new_particle(Particle(sp, Real3(L / 2, L / 2, L * 5 / 6), + 2.5e-9, 1e-12))); // This should fail + BOOST_CHECK(world->new_particle(Particle( + sp, Real3(L / 2, L / 2, L * 5 / 6 - voxel_radius), 2.5e-9, 1e-12))); sim.initialize(); diff --git a/ecell4/spatiocyte/tests/SpatiocyteWorld_test.cpp b/ecell4/spatiocyte/tests/SpatiocyteWorld_test.cpp index cd614cd36..6ef3d4376 100644 --- a/ecell4/spatiocyte/tests/SpatiocyteWorld_test.cpp +++ b/ecell4/spatiocyte/tests/SpatiocyteWorld_test.cpp @@ -1,40 +1,46 @@ #define BOOST_TEST_MODULE "SpatiocyteWorld_test" #ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -# include +#include #else -# define BOOST_TEST_NO_LIB -# include +#define BOOST_TEST_NO_LIB +#include #endif #include +#include "../OffLattice.hpp" #include "../SpatiocyteWorld.hpp" -#include "../../core/Sphere.hpp" -//#include +#include +#include #include using namespace ecell4; using namespace ecell4::spatiocyte; -const Real DEFAULT_VOXEL_RADIUS = 1e-8; - -BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_constructor) +struct Fixture { - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - const Real3 edge_lengths(1e-6, 1e-6, 1e-6); - const Real voxel_radius(DEFAULT_VOXEL_RADIUS); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); -} + const Real3 edge_lengths; + const Real voxel_radius; + const boost::shared_ptr rng; + const boost::shared_ptr model; + SpatiocyteWorld world; + + Fixture() + : edge_lengths(1e-6, 1e-6, 1e-6), voxel_radius(1e-8), + rng(new GSLRandomNumberGenerator()), model(new NetworkModel()), + world(edge_lengths, voxel_radius, rng) + { + world.bind_to(model); + } +}; + +BOOST_FIXTURE_TEST_SUITE(suite, Fixture) + +BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_constructor) {} BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_t) { - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - const Real3 edge_lengths(1e-6, 1e-6, 1e-6); - const Real voxel_radius(DEFAULT_VOXEL_RADIUS); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); BOOST_CHECK_EQUAL(world.t(), 0); world.set_t(23.4); BOOST_CHECK_EQUAL(world.t(), 23.4); @@ -42,45 +48,45 @@ BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_t) BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_num_species) { - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - const Real3 edge_lengths(1e-6, 1e-6, 1e-6); - const Real voxel_radius(DEFAULT_VOXEL_RADIUS); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); BOOST_CHECK_EQUAL(world.list_species().size(), 0); } BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_has_species) { - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - const Real3 edge_lengths(1e-6, 1e-6, 1e-6); - const Real voxel_radius(DEFAULT_VOXEL_RADIUS); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); Species sp(std::string("Species")); BOOST_CHECK(!world.has_species(sp)); } BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_list_particles) { - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - const Real3 edge_lengths(1e-6, 1e-6, 1e-6); - const Real voxel_radius(DEFAULT_VOXEL_RADIUS); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); - std::vector > particles(world.list_particles()); + std::vector> particles( + world.list_particles()); BOOST_CHECK_EQUAL(particles.size(), 0); } +BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_get_molecule_info) +{ + const Species m("M", voxel_radius, 0.0); + const Species a("A", voxel_radius, 1.0, "M"); + model->add_species_attribute(m); + model->add_species_attribute(a); + + const auto info_m = world.get_molecule_info(m); + BOOST_CHECK_EQUAL(info_m.radius, voxel_radius); + BOOST_CHECK_EQUAL(info_m.D, 0.0); + BOOST_CHECK_EQUAL(info_m.loc, ""); + BOOST_CHECK_EQUAL(info_m.dimension, Shape::THREE); + + const auto info_a = world.get_molecule_info(a); + BOOST_CHECK_EQUAL(info_a.radius, voxel_radius); + BOOST_CHECK_EQUAL(info_a.D, 1.0); + BOOST_CHECK_EQUAL(info_a.loc, "M"); + BOOST_CHECK_EQUAL(info_a.dimension, Shape::THREE); +} + BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_update_particles) { - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); SerialIDGenerator sidgen; - const Real3 edge_lengths(1e-6, 1e-6, 1e-6); - const Real voxel_radius(DEFAULT_VOXEL_RADIUS); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); - ParticleID pid(sidgen()); Species sp(std::string("A")); const Real3 pos(2e-7, 1e-7, 0); @@ -88,6 +94,7 @@ BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_update_particles) Real d(0); Particle p(sp, pos, r, d); + model->add_species_attribute(sp); world.update_particle(pid, p); BOOST_CHECK(world.has_species(sp)); @@ -98,34 +105,21 @@ BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_update_particles) // BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_register_species) // { -// const Real3 edge_lengths(1e-6,1e-6,1e-6); -// const Real voxel_radius(DEFAULT_VOXEL_RADIUS); -// boost::shared_ptr -// rng(new GSLRandomNumberGenerator()); -// SpatiocyteWorld world(edge_lengths, voxel_radius, rng); -// // Species sp(std::string("TEST")); -// +// // BOOST_CHECK(world.register_species(sp)); // BOOST_CHECK(world.has_species(sp)); -// +// // std::vector list; // list.push_back(sp); -// +// // BOOST_CHECK(list == world.list_species()); // } BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_add_molecule) { - const Real3 edge_lengths(1e-6,1e-6,1e-6); - const Real voxel_radius(2.5e-9); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); - - Species sp(std::string("TEST")); - sp.set_attribute("radius", 2.5e-9); - sp.set_attribute("D", 1e-12); + const Species sp("TEST", 1e-8, 1e-12); + model->add_species_attribute(sp); const Voxel voxel(world.get_voxel_nearby(edge_lengths / 2.0)); // BOOST_CHECK(world.place_voxel(sp, coord).second); @@ -138,45 +132,34 @@ BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_add_molecule) BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_add_molecules) { - const Real3 edge_lengths(1e-6,1e-6,1e-6); - const Real voxel_radius(DEFAULT_VOXEL_RADIUS); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); - - Species sp(std::string("TEST")); - sp.set_attribute("radius", 2.5e-9); - sp.set_attribute("D", 1e-12); - const Integer N(60); + const Species sp("TEST", 1e-8, 1e-12); + model->add_species_attribute(sp); + const Integer N(60); BOOST_CHECK(world.add_molecules(sp, N)); BOOST_CHECK_EQUAL(world.num_particles(sp), N); } BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_neighbor) { - const Real3 edge_lengths(1e-6,1e-6,1e-6); - const Real voxel_radius(DEFAULT_VOXEL_RADIUS); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); - const Voxel voxel(world.get_voxel_nearby(edge_lengths / 2.0)); const Real3 cp(voxel.position()); - Species sp(std::string("TEST")); - sp.set_attribute("radius", 2.5e-9); - sp.set_attribute("D", 1e-12); - for (Integer i(0); i < voxel.num_neighbors(); ++i) + const Species sp("TEST", 1e-8, 1e-12); + model->add_species_attribute(sp); + + for (Integer i(0); i < world.num_neighbors(voxel); ++i) { - world.new_particle(sp, voxel.get_neighbor(i)); + world.new_particle(sp, world.get_neighbor(voxel, i)); } - std::vector > particles(world.list_particles()); - for (std::vector >::iterator itr( - particles.begin()); itr != particles.end(); ++itr) + std::vector> particles( + world.list_particles()); + for (std::vector>::iterator itr( + particles.begin()); + itr != particles.end(); ++itr) { Real3 pos((*itr).second.position()); - BOOST_ASSERT(length(pos-cp) < voxel_radius*2.1); + BOOST_ASSERT(length(pos - cp) < voxel_radius * 2.1); } #ifdef WITH_HDF5 @@ -186,17 +169,11 @@ BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_neighbor) BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_add_shape) { - const Real3 edge_lengths(1e-6,1e-6,1e-6); - const Real voxel_radius(DEFAULT_VOXEL_RADIUS); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); + const Species sp("TEST", 1e-8, 1e-12); + model->add_species_attribute(sp); - Species sp(std::string("TEST")); - sp.set_attribute("radius", 2.5e-9); - sp.set_attribute("D", 1e-12); - - boost::shared_ptr sphere(new Sphere(Real3(5e-7, 5e-7, 5e-7), 5e-7*1.5)); + boost::shared_ptr sphere( + new Sphere(Real3(5e-7, 5e-7, 5e-7), 5e-7 * 1.5)); const Integer n(world.add_structure(sp, sphere)); BOOST_ASSERT(n > 0); @@ -209,15 +186,8 @@ BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_add_shape) BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_move) { - const Real3 edge_lengths(1e-6,1e-6,1e-6); - const Real voxel_radius(2.5e-9); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); - - Species sp(std::string("TEST")); - sp.set_attribute("radius", 2.5e-9); - sp.set_attribute("D", 1e-12); + const Species sp("TEST", 1e-8, 1e-12); + model->add_species_attribute(sp); const Voxel from(world.get_voxel_nearby(Real3(0.3e-6, 0.5e-6, 0.5e-6))); const Voxel to(world.get_voxel_nearby(Real3(0.5e-6, 0.5e-6, 0.5e-6))); @@ -233,24 +203,53 @@ BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_move) BOOST_AUTO_TEST_CASE(SpatiocyteWorld_test_structure) { - const Real3 edge_lengths(5e-7, 5e-7, 5e-7); - const Real voxel_radius(DEFAULT_VOXEL_RADIUS); - boost::shared_ptr - rng(new GSLRandomNumberGenerator()); - SpatiocyteWorld world(edge_lengths, voxel_radius, rng); - - Species membrane("Membrane", 2.5e-9, 0); - - Species sp("SpeciesA", 2.5e-9, 1e-12); - sp.set_attribute("location", "Membrane"); + const Species membrane("Membrane", 2.5e-9, 0); + const Species sp("TEST", 1e-8, 1e-12, "Membrane"); + model->add_species_attribute(membrane); + model->add_species_attribute(sp); - boost::shared_ptr sphere(new Sphere(Real3(2.5e-7, 2.5e-7, 2.5e-7), 2e-7)); + boost::shared_ptr sphere( + new Sphere(Real3(2.5e-7, 2.5e-7, 2.5e-7), 2e-7)); BOOST_CHECK(world.add_structure(membrane, sphere) == 5892); - BOOST_CHECK(!world.new_particle(Particle(sp, Real3(2.5e-7, 2.5e-7, 4.5e-7), 2.5e-9, 1e-12))); - BOOST_CHECK(world.new_particle(Particle(sp, Real3(2.5e-7, 2.5e-7, 4.5e-7 - voxel_radius * 2), 2.5e-9, 1e-12))); + BOOST_CHECK(!world.new_particle( + Particle(sp, Real3(2.5e-7, 2.5e-7, 4.5e-7), 2.5e-9, 1e-12))); + BOOST_CHECK(world.new_particle(Particle( + sp, Real3(2.5e-7, 2.5e-7, 4.5e-7 - voxel_radius * 2), 2.5e-9, 1e-12))); #ifdef WITH_HDF5 world.save("structure.h5"); #endif } + +BOOST_AUTO_TEST_CASE(SpatiocyteWorld_offlattice) +{ + const Species membrane("M", voxel_radius, 0.0); + const Species speciesA("A", voxel_radius, 1e-12, "M"); + model->add_species_attribute(membrane); + model->add_species_attribute(speciesA); + + std::vector positions; + for (auto i = 0; i < 100; ++i) + { + for (auto j = 0; j < 100; ++j) + { + positions.push_back(Real3(i * 1e-8, j * 1e-8, 0.5e-6)); + } + } + + const OffLattice offlattice(voxel_radius, positions); + world.add_space(offlattice.generate_space(membrane)); + BOOST_CHECK_EQUAL(world.num_particles(membrane), 10000); + + // Check whether molecules can be placed at OffLattice. + BOOST_CHECK(world.add_molecules(speciesA, 100)); + BOOST_CHECK_EQUAL(world.num_particles(speciesA), 100); + BOOST_CHECK_EQUAL(world.num_particles(membrane), 9900); + + // Check whether neighbor voxels can be accessed across spaces. + const auto voxel = world.list_voxels_exact(speciesA).at(0).voxel; + BOOST_CHECK(world.check_neighbor(voxel, "")); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/ecell4/spatiocyte/utils.cpp b/ecell4/spatiocyte/utils.cpp index 61bb98c14..905f8fac7 100644 --- a/ecell4/spatiocyte/utils.cpp +++ b/ecell4/spatiocyte/utils.cpp @@ -1,6 +1,5 @@ #include "utils.hpp" - namespace ecell4 { @@ -8,23 +7,19 @@ namespace spatiocyte { const Real calculate_dimensional_factor( - boost::shared_ptr mt0, boost::shared_ptr mt1, + boost::shared_ptr mt0, const Real D_A, + boost::shared_ptr mt1, const Real D_B, boost::shared_ptr world) { const Real voxel_radius(world->voxel_radius()); const Real unit_area(world->unit_area()); - const Species - speciesA(mt0->species()), - speciesB(mt1->species()); - const Real - D_A(mt0->D()), - D_B(mt1->D()); - const Shape::dimension_kind - dimensionA(world->get_dimension(speciesA)), + const Species speciesA(mt0->species()), speciesB(mt1->species()); + const Shape::dimension_kind dimensionA(world->get_dimension(speciesA)), dimensionB(world->get_dimension(speciesB)); const Real Dtot(D_A + D_B); - const Real gamma(pow(2 * sqrt(2.0) + 4 * sqrt(3.0) + 3 * sqrt(6.0) + sqrt(22.0), 2) / + const Real gamma( + pow(2 * sqrt(2.0) + 4 * sqrt(3.0) + 3 * sqrt(6.0) + sqrt(22.0), 2) / (72 * (6 * sqrt(2.0) + 4 * sqrt(3.0) + 3 * sqrt(6.0)))); Real factor(0); if (dimensionA == Shape::THREE && dimensionB == Shape::THREE) @@ -60,50 +55,54 @@ const Real calculate_dimensional_factor( } } else - throw NotSupported("The dimension of a structure must be two or three."); + throw NotSupported( + "The dimension of a structure must be two or three."); return factor; } -const Real calculate_alpha(const ReactionRule& rr, const boost::shared_ptr& world) +const Real calculate_alpha(const ReactionRule &rr, + const boost::shared_ptr &world) { - const ReactionRule::reactant_container_type& reactants(rr.reactants()); + const ReactionRule::reactant_container_type &reactants(rr.reactants()); if (reactants.size() != 2) return 1.0; else if (rr.k() == std::numeric_limits::infinity()) return 1.0; const Species species[2] = {reactants.at(0), reactants.at(1)}; - const MoleculeInfo info[2] = { - world->get_molecule_info(species[0]), - world->get_molecule_info(species[1]) - }; + const MoleculeInfo info[2] = {world->get_molecule_info(species[0]), + world->get_molecule_info(species[1])}; boost::shared_ptr mt[2]; - for (int i(0); i < 2; ++i) { + for (int i(0); i < 2; ++i) + { try { mt[i] = world->find_voxel_pool(species[i]); } - catch(NotFound e) + catch (NotFound e) { boost::weak_ptr location(world->vacant()); - if (info[i].loc != "") { + if (info[i].loc != "") + { try { location = world->find_voxel_pool(Species(info[i].loc)); } - catch(NotFound e) + catch (NotFound e) { ; } } - mt[i] = boost::shared_ptr(new MoleculePool(species[i], location, info[i].radius, info[i].D)); + mt[i] = boost::shared_ptr( + new MoleculePool(species[i], location)); } } - const Real factor(calculate_dimensional_factor(mt[0], mt[1], world)); + const Real factor(calculate_dimensional_factor(mt[0], info[0].D, mt[1], + info[1].D, world)); const Real alpha(1.0 / (factor * rr.k())); return alpha < 1.0 ? alpha : 1.0; } -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 diff --git a/ecell4/spatiocyte/utils.hpp b/ecell4/spatiocyte/utils.hpp index b4e6b7a7b..fa6c3d8fe 100644 --- a/ecell4/spatiocyte/utils.hpp +++ b/ecell4/spatiocyte/utils.hpp @@ -10,14 +10,15 @@ namespace spatiocyte { const Real calculate_dimensional_factor( - boost::shared_ptr mt0, boost::shared_ptr mt1, + boost::shared_ptr mt0, const Real D_A, + boost::shared_ptr mt1, const Real D_B, boost::shared_ptr world); -const Real calculate_alpha( - const ReactionRule& rr, const boost::shared_ptr& world); +const Real calculate_alpha(const ReactionRule &rr, + const boost::shared_ptr &world); -} // spatiocyte +} // namespace spatiocyte -} // ecell4 +} // namespace ecell4 #endif /* ECELL4_SPATIOCYTE_UTILS_HPP */ diff --git a/tests/spatiocyte/__init__.py b/tests/spatiocyte/__init__.py new file mode 100644 index 000000000..6fa09ad8f --- /dev/null +++ b/tests/spatiocyte/__init__.py @@ -0,0 +1,2 @@ +from ecell4_base.core import * +from ecell4_base.spatiocyte import * diff --git a/tests/spatiocyte/offlattice.py b/tests/spatiocyte/offlattice.py new file mode 100644 index 000000000..1dc730f8d --- /dev/null +++ b/tests/spatiocyte/offlattice.py @@ -0,0 +1,36 @@ +import unittest +from ecell4_base.core import * +from ecell4_base.spatiocyte import * + +class OffLatticeTest(unittest.TestCase): + + def setUp(self): + self.voxel_radius = 0.005 + + coordinates = [Real3(x, 0.0, 0.0) for x in range(0,10)] + connections = [(x, x+1) for x in range(0,9)] + self.offlattice = OffLattice(self.voxel_radius, coordinates, connections) + + def test_constructor(self): + species = Species('Base') + model = NetworkModel() + model.add_species_attribute(species) + + world = SpatiocyteWorld(ones(), self.voxel_radius) + world.bind_to(model) + world.add_offlattice(species, self.offlattice) + + def test_add_molecules(self): + base = Species('Base', radius=self.voxel_radius, D=0.0) + species = Species('A', radius=self.voxel_radius, D=1.0, location='Base') + + model = NetworkModel() + model.add_species_attribute(base) + model.add_species_attribute(species) + + world = SpatiocyteWorld(ones(), self.voxel_radius) + world.bind_to(model) + world.add_offlattice(base, self.offlattice) + + world.add_molecules(species, 5) + self.assertEqual(5, world.num_molecules(species))