Example #1
0
int MakeBoxDomains(const Box &box,int nproc, int nx, int ny, int nz, inp_it result){
  int ndir[3]={nx,ny,nz}, nspl[3]={nx,ny,nz};
  int np=(nproc>0 ? nproc : -nproc);
  int startdir=2;
  int dd, curdir=-1;
  // getting minimal splits
  int nauto=0, autod[3]={-1, -1, -1}, ndef=0;
  for(dd=0;dd<3;dd++){
    int dir=(dd+startdir)%3;
    if(ndir[dir]>0 && ndir[dir]>curdir)curdir=dir;
    else if(ndir[dir]<0){
      autod[nauto++]=dir;
    }
    if(ndir[dir]==0)ndef++;
  }
  if(curdir<0 && nauto>0){
    if(nauto==1){
      ndir[autod[0]]=np;
      curdir=autod[0];
    }
    else{  // auto-finding direction and number of slices to split
      int i;
      vec_type lprod=1.;
      for(i=0;i<nauto;i++){
        lprod*=box.GetSize()[autod[i]];
      }
      vec_type k=pow((vec_type)np/lprod,vec_type(1)/vec_type(nauto));
      int mnp=0, mdir=0;
      for(i=0;i<nauto;i++){
        int tnp=(int)(box.GetSize()[autod[i]]*k);
        if(mnp<tnp){
          mnp=tnp;
          mdir=i;
        }
      }
      if(mnp>0){
        ndir[autod[mdir]]=mnp;
        curdir=autod[mdir];
      }
    }
  }
  if(curdir>=0){ // splitting by minimal dir, auto split is ignored
    // number of domains
    int ndom=0;
    // determining sub-nps
    // THIS IS NP SWITCH : !!!
    if(np<ndir[curdir])ndir[curdir]=np;
    if(np>ndir[curdir] && ndef==2){ // the last axis
      ndir[curdir]=np;
    }

    int snp=(np>ndir[curdir] ? np : ndir[curdir]);
    int mnp=snp/ndir[curdir]; // minimal np
    int dntot=snp%ndir[curdir]; // difference
    vec_type c0=(vec_type)mnp/snp, c1=(vec_type)(mnp+1)/snp;
    Vector_3 p1=box.get_p1();
    Vector_3 p2=box.get_p2();
    
    vec_type l=box.GetSize()[curdir];
    int i;
    for(i=0;i<ndir[curdir];i++){
      vec_type dl=(dntot>0 ? l*c1 : l*c0);
      int cnp=(dntot>0 ? mnp+1 : mnp);
      if(cnp<=0)break;
      dntot--;
      p2[curdir]=p1[curdir]+dl;
      Box subdiv(p1,p2);
      nspl[curdir]=0; // this direction is processed
      int ddom=MakeBoxDomains(subdiv,(nproc>0 ? cnp: -cnp),nspl[0],nspl[1],nspl[2],result);
      if(nproc>0)result+=ddom;
      ndom+=ddom;
      p1[curdir]=p2[curdir];
    }
    return ndom;
  }
  /// called with  (0,0,0) split: put this box into the set
  if(nproc>0)
    *result=box;
  return 1;   
}
Example #2
0
 vec_type normal() const
 {
   vec_type _d = p_[1] - p_[0];
   return vec_type(-_d.y(),_d.x());
 }