#include "mcontainer.h" #include "warning.h" namespace blop { int mcontainer::ind(int i, int j) const { --i; --j; if(i < 0) i = 0; if(i >= nx_) i = nx_-1; if(j < 0) j = 0; if(j >= ny_) j = ny_-1; int result = i * ny_ + j; return result; } mcontainer &mcontainer::direction(int i) { direction_ = i; cd_first(); return *this; } void mcontainer::init_(int xdim, int ydim, int dir) { direction_ = dir; nx_ = xdim; ny_ = ydim; current_ix_ = 1; current_iy_ = 1; } mcontainer::mcontainer(int xdim, int ydim, int dir) { init_(xdim,ydim,dir); } mcontainer::mcontainer() : direction_(0), nx_(0), ny_(0), current_ix_(0), current_iy_(0) { } void mcontainer::get_gridsize_(int n, int &xdim, int &ydim) { xdim = ydim = std::floor(std::sqrt((double)n)); while(xdim*ydim<n) { ++ydim; if(xdim*ydim>=n) break; ++xdim; } } mcontainer &mcontainer::cd_first() { if (direction_&right_down) cd(1, ny_); else if(direction_&right_up ) cd(1, 1 ); else if(direction_&left_down ) cd(nx_,ny_); else if(direction_&left_up ) cd(nx_,1 ); else { warning::print("No direction is set (should not happen)","mcontainer::cd_first()"); cd(1, 1 ); } return *this; } bool mcontainer::cd_next() { int cur_ix = current_ix_; int cur_iy = current_iy_; if( (direction_ & right_down) || (direction_ & right_up) ) { if(++cur_ix > nx_) { cur_ix = 1; if(direction_ & right_down) { if(--cur_iy <= 0) { if( (direction_&jump) == 0) return false; cur_iy = ny_; } } else { if(++cur_iy > ny_) { if( (direction_&jump) == 0) return false; cur_iy = 1; } } } } else if( (direction_ & left_down) || (direction_ & left_up) ) { if(--cur_ix <= 0) { cur_ix = nx_; if(direction_ & left_down) { if(--cur_iy <= 0) { if( (direction_&jump) == 0) return false; cur_iy = ny_; } } else { if(++cur_iy > ny_) { if( (direction_&jump) == 0) return false; cur_iy = 1; } } } } else if( (direction_ & down_left) || (direction_ & down_right) ) { if(--cur_iy <= 0) { cur_iy = ny_; if(direction_ & down_left) { if(--cur_ix <= 0) { if( (direction_&jump) == 0) return false; cur_ix = nx_; } } else { if(++cur_ix > nx_) { if( (direction_&jump) == 0) return false; cur_ix = 1; } } } } else if( (direction_ & up_left) || (direction_ & up_right) ) { if(++cur_iy > ny_) { cur_iy = 1; if(direction_ & up_left) { if(--cur_ix <= 0) { if( (direction_&jump) == 0) return false; cur_ix = nx_; } } else { if(++cur_ix > nx_) { if( (direction_&jump) == 0) return false; cur_ix = 1; } } } } else { warning::print("Bad direction","mcontainer::cd_next()"); return false; } cd(cur_ix, cur_iy); return true; } mcontainer &mcontainer::cd(int i, int j) { current_ix_ = i; current_iy_ = j; cd_to_sub_(ind(i,j)); return *this; } mcontainer &mcontainer::cd(int i) { if(i<1 || nx_*ny_<i) { warning::print("Subcontainer number is out of range", "mcontainer::cd(" & var(i) & ")"); return *this; } --i; if (direction_&right_down ) cd(1+i%nx_, ny_-i/nx_); else if(direction_&down_right ) cd(1+i/ny_, ny_-i%ny_); else if(direction_&right_up ) cd(1+i%nx_, 1+i/nx_ ); else if(direction_&up_right ) cd(1+i/ny_, 1+i%ny_ ); else if(direction_&left_down ) cd(nx_-i%ny_, ny_-i/ny_); else if(direction_&down_left ) cd(nx_-i/ny_, ny_-i%ny_); else if(direction_&left_up ) cd(nx_-i%ny_, 1+i/ny_ ); else if(direction_&up_left ) cd(nx_-i/ny_, 1+i%ny_ ); else warning::print("Bad direction of mcontainer, this should not happen"); return *this; } }