/* **** MppDomain.cpp **** MppDomain package NOTE: only mpi is implemented here. if needed, shmem version will be added on in the future. Contact: Zhi.Liang@noaa.gov */ #include #include #include "mpp.h" #include "mpp_domain.h" /*********************************************************** global variables ***********************************************************/ int pe, npes, root_pe; /************************************************************ void mpp_domain_init() initialization routine. get the processor information. memory allocation. ************************************************************/ void mpp_domain_init( ) { pe = mpp_pe(); npes = mpp_npes(); root_pe = mpp_root_pe(); }; /* mpp_domain_init */ /*********************************************************** void mpp_domain_end() release memory. ***********************************************************/ void mpp_domain_end () { /* will add something here if needed */ }; /************************************************************ void mpp_define_layout() define domain layout based on given grid resolution and number of processors ***********************************************************/ void mpp_define_layout(int ni, int nj, int ndivs, int layout[]) { int idiv, jdiv; float fdiv; /*first try to divide ndivs in the domain aspect ratio: if imperfect aspect, reduce idiv till it divides ndivs */ fdiv = sqrt((1.0*ndivs*ni)/nj); idiv = floor(fdiv); if(fdiv-idiv > 0.5) idiv = idiv + 1; idiv = (idiv>1) ? idiv : 1; /*for isz=1 line above can give 0*/ while( ndivs%idiv != 0 ) { idiv = idiv - 1; } /*will terminate at idiv=1 if not before*/ jdiv = ndivs/idiv; layout[0] = idiv; layout[1] = jdiv; }; /*********************************************************** void mpp_define_domain_1d(int size, domain1D *domain ) define 1-D domain decomposition. **********************************************************/ void mpp_define_domain_1d(int npts, int ndivs, domain1D *domain ) { int n, npts_left, pos, size; domain->beglist = (int *)malloc(ndivs*sizeof(int)); domain->endlist = (int *)malloc(ndivs*sizeof(int)); if(ndivs > npts ) { mpp_error("mpp_define_domain1d: more divisions requested than rows available. " ); } npts_left = npts; pos = 0; for(n=0; nbeglist[n] = pos; size = ceil((1.0*npts_left)/(ndivs-n)); domain->endlist[n] = pos + size - 1; npts_left=npts_left - size; pos += size; } if(npes == ndivs) { domain->start = domain->beglist[pe]; domain->end = domain->endlist[pe]; domain->size = domain->end - domain->start + 1; domain->sizeg = npts; } }; /* mpp_define_domain_1d */ /************************************************************ void define_domain(int ni, int nj, int layout[], int xhalo, int yhalo, domain2D *domain ) define 2D domain decomposition ************************************************************/ void mpp_define_domain2d(int ni, int nj, int layout[], int xhalo, int yhalo, domain2D *domain ) { domain1D domx, domy; int i, j, posx, posy, n; domain->isclist = (int *)malloc(layout[0]*layout[1]*sizeof(int)); domain->ieclist = (int *)malloc(layout[0]*layout[1]*sizeof(int)); domain->jsclist = (int *)malloc(layout[0]*layout[1]*sizeof(int)); domain->jeclist = (int *)malloc(layout[0]*layout[1]*sizeof(int)); mpp_define_domain_1d(ni, layout[0], &domx); mpp_define_domain_1d(nj, layout[1], &domy); n = 0; for(j=0; jisclist[n] = domx.beglist[i]+xhalo; domain->ieclist[n] = domx.endlist[i]+xhalo; domain->jsclist[n] = domy.beglist[j]+yhalo; domain->jeclist[n] = domy.endlist[j]+yhalo; n++; } } domain->xhalo = xhalo; domain->yhalo = yhalo; domain->isc = domain->isclist[pe]; domain->iec = domain->ieclist[pe]; domain->jsc = domain->jsclist[pe]; domain->jec = domain->jeclist[pe]; domain->isd = domain->isc - xhalo; domain->ied = domain->iec + xhalo; domain->jsd = domain->jsc - yhalo; domain->jed = domain->jec + yhalo; domain->nxc = domain->iec - domain->isc + 1; domain->nyc = domain->jec - domain->jsc + 1; domain->nxd = domain->ied - domain->isd + 1; domain->nyd = domain->jed - domain->jsd + 1; domain->nxg = ni; domain->nyg = nj; mpp_delete_domain1d(&domx); mpp_delete_domain1d(&domy); }; /* mpp_define_domain2d */ /**************************************************************************** void mpp_delete_domain1d(domain1D *domain); release the memory assigned to 1-D domain *****************************************************************************/ void mpp_delete_domain1d(domain1D *domain) { free(domain->beglist); free(domain->endlist); }; /* mpp_delete_domain1d */ /**************************************************************************** void mpp_delete_domain2d(domain2D *domain); release the memory assigned to 2-D domain *****************************************************************************/ void mpp_delete_domain2d(domain2D *domain) { free(domain->isclist); free(domain->ieclist); free(domain->jsclist); free(domain->jeclist); }; /* mpp_delete_domain2d */ /*********************************************************** void get_get_compute_domain(omain2D domain, int *is, int *ie, int *js, int *je) get the compute domain decomposition ***********************************************************/ void mpp_get_compute_domain2d(domain2D domain, int *is, int *ie, int *js, int *je) { *is = domain.isc; *ie = domain.iec; *js = domain.jsc; *je = domain.jec; }; /* mpp_get_compute_domain */ /*********************************************************** void get_get_compute_domain( int *is, int *ie, int *js, int *je) get the compute domain decomposition of current pe list. ***********************************************************/ void mpp_get_compute_domains2d(domain2D domain, int *is, int *ie, int *js, int *je) { int n; for(n=0; n0) mpp_send_int(ldata, lsize, p); } } n = 0; /* receive from other pe and fill the gdata */ for(p = 0; p0) { rbuffer = ( int *) malloc(rsize[p]*sizeof(int)); mpp_recv_int(rbuffer, rsize[p], p ); for(i=0; i0) mpp_send_double(ldata, lsize, p); } } n = 0; /* receive from other pe and fill the gdata */ for(p = 0; p0) { rbuffer = (double *) malloc(rsize[p]*sizeof(double)); mpp_recv_double(rbuffer, rsize[p], p ); for(i=0; i