void psht_make_rectangular_alm_info (int lmax, int mmax, int stride, psht_alm_info **alm_info) { ptrdiff_t m; psht_alm_info *info = RALLOC(psht_alm_info,1); info->lmax = lmax; info->mmax = mmax; info->mstart = RALLOC(ptrdiff_t,mmax+1); info->stride = stride; for (m=0; m<=mmax; ++m) info->mstart[m] = stride*m*(lmax+1); *alm_info = info; }
void psht_make_alm_info (int lmax, int mmax, int stride, const ptrdiff_t *mstart, psht_alm_info **alm_info) { int m; psht_alm_info *info = RALLOC(psht_alm_info,1); info->lmax = lmax; info->mmax = mmax; info->mstart = RALLOC(ptrdiff_t,mmax+1); info->stride = stride; for (m=0; m<=mmax; ++m) info->mstart[m] = mstart[m]; *alm_info = info; }
void psht_make_triangular_alm_info (int lmax, int mmax, int stride, psht_alm_info **alm_info) { ptrdiff_t m; int tval; psht_alm_info *info = RALLOC(psht_alm_info,1); info->lmax = lmax; info->mmax = mmax; info->mstart = RALLOC(ptrdiff_t,mmax+1); info->stride = stride; tval = 2*lmax+1; for (m=0; m<=mmax; ++m) info->mstart[m] = stride*((m*(tval-m))>>1); *alm_info = info; }
void psht_make_gauss_geom_info_2 (int nrings, int nphi, int stride_lon, int stride_lat, psht_geom_info **geom_info) { const double pi=3.141592653589793238462643383279502884197; double *theta=RALLOC(double,nrings); double *weight=RALLOC(double,nrings); int *nph=RALLOC(int,nrings); double *phi0=RALLOC(double,nrings); ptrdiff_t *ofs=RALLOC(ptrdiff_t,nrings); int *stride_=RALLOC(int,nrings); int m; gauleg(-1,1,theta,weight,nrings); for (m=0; m<nrings; ++m) { theta[m] = acos(theta[m]); nph[m]=nphi; phi0[m]=0; ofs[m]=(ptrdiff_t)m*stride_lat; stride_[m]=stride_lon; weight[m]*=2*pi/nphi; } psht_make_geom_info (nrings, nph, ofs, stride_, phi0, theta, weight, geom_info); DEALLOC(theta); DEALLOC(weight); DEALLOC(nph); DEALLOC(phi0); DEALLOC(ofs); DEALLOC(stride_); }
static void mkspacep(int size) { if (size > maxpn) { int newmax = maxpn + (size / PINC + 1) * PINC; ps = RALLOC(newmax, ps, point); maxpn = newmax; } }
void psht_make_geom_info (int nrings, const int *nph, const ptrdiff_t *ofs, const int *stride, const double *phi0, const double *theta, const double *weight, psht_geom_info **geom_info) { psht_geom_info *info = RALLOC(psht_geom_info,1); psht_ringinfo *infos = RALLOC(psht_ringinfo,nrings); int pos=0; int m; info->pair=RALLOC(psht_ringpair,nrings); info->npairs=0; *geom_info = info; for (m=0; m<nrings; ++m) { infos[m].theta = theta[m]; infos[m].cth = cos(theta[m]); infos[m].sth = sin(theta[m]); infos[m].weight = weight[m]; infos[m].phi0 = phi0[m]; infos[m].ofs = ofs[m]; infos[m].stride = stride[m]; infos[m].nph = nph[m]; } qsort(infos,nrings,sizeof(psht_ringinfo),ringinfo_compare); while (pos<nrings) { if ((pos<nrings-1) && FAPPROX(infos[pos].cth,-infos[pos+1].cth,1e-12)) { info->pair[info->npairs].r1=infos[pos]; info->pair[info->npairs].r2=infos[pos+1]; pos+=2; ++info->npairs; } else { info->pair[info->npairs].r1=infos[pos]; info->pair[info->npairs].r2.nph=-1; ++pos; ++info->npairs; } } DEALLOC(infos); qsort(info->pair,info->npairs,sizeof(psht_ringpair),ringpair_compare); }
static void alloc_phase_mpi (sharp_job *job, int nm, int ntheta, int nmfull, int nthetafull) { ptrdiff_t phase_size = (job->type==SHARP_MAP2ALM) ? (ptrdiff_t)(nmfull)*ntheta : (ptrdiff_t)(nm)*nthetafull; job->phase=RALLOC(dcmplx,2*job->ntrans*job->nmaps*phase_size); job->s_m=2*job->ntrans*job->nmaps; job->s_th = job->s_m * ((job->type==SHARP_MAP2ALM) ? nmfull : nm); }
static pointf *mkOverlapSet(info * nl, int nn, int *cntp) { info *p = nl; info *q; int sz = nn; pointf *S = N_GNEW(sz + 1, pointf); int i, j; int cnt = 0; for (i = 0; i < nn; i++) { q = p + 1; for (j = i + 1; j < nn; j++) { if (overlap(p->bb, q->bb)) { pointf pt; if (cnt == sz) { sz += nn; S = RALLOC(sz + 1, S, pointf); } if (p->pos.x == q->pos.x) pt.x = HUGE_VAL; else { pt.x = (p->wd2 + q->wd2) / fabs(p->pos.x - q->pos.x); if (pt.x < 1) pt.x = 1; } if (p->pos.y == q->pos.y) pt.y = HUGE_VAL; else { pt.y = (p->ht2 + q->ht2) / fabs(p->pos.y - q->pos.y); if (pt.y < 1) pt.y = 1; } S[++cnt] = pt; } q++; } p++; } S = RALLOC(cnt + 1, S, pointf); *cntp = cnt; return S; }
complex_plan copy_complex_plan (complex_plan plan) { if (!plan) return NULL; { complex_plan newplan = RALLOC(complex_plan_i,1); *newplan = *plan; newplan->work=RALLOC(double,newplan->worksize); memcpy(newplan->work,plan->work,sizeof(double)*newplan->worksize); return newplan; } }
static void mkspacep(int size) { if (size > maxpn) { int newmax = maxpn + (size / PINC + 1) * PINC; ps = RALLOC(newmax, ps, pointf); if (!ps) { agerr(AGERR, "cannot re-allocate ps\n"); abort(); } maxpn = newmax; } }
boxf* partition (cell* cells, int ncells, int* nrects, boxf bb) { int nsegs = 4*(ncells+1); segment_t* segs = N_GNEW(nsegs+1, segment_t); int* permute = N_NEW(nsegs+1, int); int hd_size, vd_size; int i, j, cnt = 0; boxf* rs; int ntraps = TRSIZE(nsegs); trap_t* trs = N_GNEW(ntraps, trap_t); boxf* hor_decomp = N_NEW(ntraps, boxf); boxf* vert_decomp = N_NEW(ntraps, boxf); int nt; /* fprintf (stderr, "cells = %d segs = %d traps = %d\n", ncells, nsegs, ntraps); */ genSegments (cells, ncells, bb, segs, 0); #if 0 fprintf (stderr, "%d\n\n", ncells+1); for (i = 1; i<= nsegs; i++) { if (i%4 == 1) fprintf(stderr, "4\n"); fprintf (stderr, "%f %f\n", segs[i].v0.x, segs[i].v0.y); if (i%4 == 0) fprintf(stderr, "\n"); } #endif srand48(173); generateRandomOrdering (nsegs, permute); nt = construct_trapezoids(nsegs, segs, permute, ntraps, trs); /* fprintf (stderr, "hor traps = %d\n", nt); */ hd_size = monotonate_trapezoids (nsegs, segs, trs, 0, hor_decomp); genSegments (cells, ncells, bb, segs, 1); generateRandomOrdering (nsegs, permute); nt = construct_trapezoids(nsegs, segs, permute, ntraps, trs); /* fprintf (stderr, "ver traps = %d\n", nt); */ vd_size = monotonate_trapezoids (nsegs, segs, trs, 1, vert_decomp); rs = N_NEW (hd_size*vd_size, boxf); for (i=0; i<vd_size; i++) for (j=0; j<hd_size; j++) if (rectIntersect(&rs[cnt], &vert_decomp[i], &hor_decomp[j])) cnt++; rs = RALLOC (cnt, rs, boxf); free (segs); free (permute); free (trs); free (hor_decomp); free (vert_decomp); *nrects = cnt; return rs; }
static int mkspacep(int size) { if (size > maxpn) { int newmax = maxpn + (size / PINC + 1) * PINC; ps = RALLOC(newmax, ps, pointf); if (!ps) { agerr(AGERR, "cannot re-allocate ps\n"); return 1; } maxpn = newmax; } return 0; }
real_plan make_real_plan (size_t length) { real_plan plan = RALLOC(real_plan_i,1); size_t pfsum = prime_factor_sum(length); double comp1 = .5*length*pfsum; double comp2 = 2*3*length*log(3.*length); comp2*=3; /* fudge factor that appears to give good overall performance */ plan->length=length; plan->bluestein = (comp2<comp1); if (plan->bluestein) bluestein_i (length,&(plan->work)); else { plan->work=RALLOC(double,2*length+15); rffti(length, plan->work); } return plan; }
complex_plan make_complex_plan (size_t length) { complex_plan plan = RALLOC(complex_plan_i,1); size_t pfsum = prime_factor_sum(length); double comp1 = (double)(length*pfsum); double comp2 = 2*3*length*log(3.*length); comp2*=3.; /* fudge factor that appears to give good overall performance */ plan->length=length; plan->bluestein = (comp2<comp1); if (plan->bluestein) bluestein_i (length,&(plan->work),&(plan->worksize)); else { plan->worksize=4*length+15; plan->work=RALLOC(double,4*length+15); cffti(length, plan->work); } return plan; }
/* setNameValue: * If arg is a name-value pair, add it to the list * and return 0; otherwise, return 1. */ static int setNameValue(char *arg) { char *p; char *rhs = "true"; if ((p = strchr(arg, '='))) { *p++ = '\0'; rhs = p; } if (G_cnt >= G_sz) { G_sz += G_CHUNK; G_args = RALLOC(G_sz, G_args, attr_t); } G_args[G_cnt].name = arg; G_args[G_cnt].value = rhs; G_cnt++; return 0; }
static void sharp_communicate_alm2map (const sharp_mpi_info *minfo, dcmplx **ph) { dcmplx *phas_tmp = RALLOC(dcmplx,minfo->mapdisp[minfo->ntasks]/2); MPI_Alltoallv (*ph,minfo->almcount,minfo->almdisp,MPI_DOUBLE,phas_tmp, minfo->mapcount,minfo->mapdisp,MPI_DOUBLE,minfo->comm); DEALLOC(*ph); ALLOC(*ph,dcmplx,minfo->nph*minfo->npair[minfo->mytask]*minfo->nmtotal); for (int task=0; task<minfo->ntasks; ++task) for (int th=0; th<minfo->npair[minfo->mytask]; ++th) for (int mi=0; mi<minfo->nm[task]; ++mi) { int m = minfo->mval[mi+minfo->ofs_m[task]]; int o1 = minfo->nph*(th*(minfo->mmax+1) + m); int o2 = minfo->mapdisp[task]/2+minfo->nph*(mi+th*minfo->nm[task]); for (int i=0; i<minfo->nph; ++i) (*ph)[o1+i] = phas_tmp[o2+i]; } DEALLOC(phas_tmp); }
void psht_make_ecp_geom_info_2 (int nrings, int nphi, double phi0, int stride_lon, int stride_lat, psht_geom_info **geom_info) { const double pi=3.141592653589793238462643383279502884197; double *theta=RALLOC(double,nrings); double *weight=RALLOC(double,nrings); int *nph=RALLOC(int,nrings); double *phi0_=RALLOC(double,nrings); ptrdiff_t *ofs=RALLOC(ptrdiff_t,nrings); int *stride_=RALLOC(int,nrings); int m; UTIL_ASSERT((nrings&1)==0, "Even number of rings needed for equidistant grid!"); makeweights(nrings/2,weight); for (m=0; m<nrings; ++m) { theta[m] = (m+0.5)*pi/nrings; nph[m]=nphi; phi0_[m]=phi0; ofs[m]=(ptrdiff_t)m*stride_lat; stride_[m]=stride_lon; weight[m]*=2*pi/nphi; } psht_make_geom_info (nrings, nph, ofs, stride_, phi0_, theta, weight, geom_info); DEALLOC(theta); DEALLOC(weight); DEALLOC(nph); DEALLOC(phi0_); DEALLOC(ofs); DEALLOC(stride_); }
/* * Name: MATLsetup * Purpose: setup the physical model parameters * Formals: cardList: list of cards to setup * Returns: OK/E_PRIVATE * Users: numerical devices * Calls: MATLcheck */ int MATLsetup(MATLcard *cardList, MaterialInfo **materialList) { MATLcard *card; MATLmaterial *newMaterial = NULL; int error; /* Initialize list of electrodes */ *materialList = NIL(MATLmaterial); /* Check the card list */ if ((error = MATLcheck( cardList ))) return( error ); for ( card = cardList; card != NIL(MATLcard); card = card->MATLnextCard ) { if (*materialList == NIL(MATLmaterial)) { RALLOC( newMaterial, MATLmaterial, 1 ); *materialList = newMaterial; } else { RALLOC( newMaterial->next, MATLmaterial, 1 ); newMaterial = newMaterial->next; } newMaterial->next = NIL(MATLmaterial); newMaterial->id = card->MATLnumber; newMaterial->material = card->MATLmaterial; /* Fill in default values */ MATLdefaults( newMaterial ); /* Now override with parameters set on the card */ if ( card->MATLpermittivityGiven ) { newMaterial->eps = card->MATLpermittivity; /* Multiply by permittivity of free space if relative epsilon given. */ if (newMaterial->eps > 0.1) { newMaterial->eps *= EPS0; } } if ( card->MATLaffinityGiven ) { newMaterial->affin = card->MATLaffinity; } if ( card->MATLnc0Given ) { newMaterial->nc0 = card->MATLnc0; } if ( card->MATLnv0Given ) { newMaterial->nv0 = card->MATLnv0; } if ( card->MATLeg0Given ) { newMaterial->eg0 = card->MATLeg0; } if ( card->MATLdEgdTGiven ) { newMaterial->dEgDt = card->MATLdEgdT; } if ( card->MATLtrefEgGiven ) { newMaterial->trefBGN = card->MATLtrefEg; } if ( card->MATLdEgdNGiven ) { newMaterial->dEgDn[ELEC] = card->MATLdEgdN; } if ( card->MATLnrefEgGiven ) { newMaterial->nrefBGN[ELEC] = card->MATLnrefEg; } if ( card->MATLdEgdPGiven ) { newMaterial->dEgDn[HOLE] = card->MATLdEgdP; } if ( card->MATLprefEgGiven ) { newMaterial->nrefBGN[HOLE] = card->MATLprefEg; } if ( card->MATLtaup0Given ) { newMaterial->tau0[HOLE] = card->MATLtaup0; } if ( card->MATLtaun0Given ) { newMaterial->tau0[ELEC] = card->MATLtaun0; } if ( card->MATLtaup0Given ) { newMaterial->tau0[HOLE] = card->MATLtaup0; } if ( card->MATLnrefSRHnGiven ) { newMaterial->nrefSRH[ELEC] = card->MATLnrefSRHn; } if ( card->MATLnrefSRHpGiven ) { newMaterial->nrefSRH[HOLE] = card->MATLnrefSRHp; } if ( card->MATLcnAugGiven ) { newMaterial->cAug[ELEC] = card->MATLcnAug; } if ( card->MATLcpAugGiven ) { newMaterial->cAug[HOLE] = card->MATLcpAug; } if ( card->MATLaRichNGiven ) { newMaterial->aRich[ELEC] = card->MATLaRichN; } if ( card->MATLaRichPGiven ) { newMaterial->aRich[HOLE] = card->MATLaRichP; } } return( OK ); }
/* * Name: ELCTsetup * Purpose: convert a list of ELCTcard's to ELCTelectrode's * Formals: cardList: list of cards to setup * electrodeList: returns the list of ELCTelectrode's * xMeshList: list of coordinates in the x mesh * yMeshList: list of coordinates in the y mesh * Returns: OK/E_PRIVATE * Users: numerical devices * Calls: ELCTcheck */ int ELCTsetup(ELCTcard *cardList, ELCTelectrode **electrodeList, MESHcoord *xMeshList, MESHcoord *yMeshList) { ELCTcard *card; ELCTelectrode *newElectrode = NULL; int ixMin, ixMax, iyMin, iyMax; int cardNum = 0; int error; char ebuf[512]; /* error message buffer */ /* Initialize list of electrodes */ *electrodeList = NULL; /* Check the card list */ if ((error = ELCTcheck( cardList )) != 0) return( error ); /* Find the limits on the indices */ MESHiBounds( xMeshList, &ixMin, &ixMax ); MESHiBounds( yMeshList, &iyMin, &iyMax ); error = OK; for ( card = cardList; card != NULL; card = card->ELCTnextCard ) { cardNum++; if (*electrodeList == NULL) { RALLOC( newElectrode, ELCTelectrode, 1 ); *electrodeList = newElectrode; } else { RALLOC( newElectrode->next, ELCTelectrode, 1 ); newElectrode = newElectrode->next; } newElectrode->next = NULL; newElectrode->id = card->ELCTnumber; newElectrode->workf = 4.10 /* electron volts */; if (card->ELCTixLowGiven) { newElectrode->ixLo = MAX(card->ELCTixLow, ixMin); } else if (card->ELCTxLowGiven) { newElectrode->ixLo = MESHlocate( xMeshList, card->ELCTxLow ); } else { newElectrode->ixLo = ixMin; } if (card->ELCTixHighGiven) { newElectrode->ixHi = MIN(card->ELCTixHigh, ixMax); } else if (card->ELCTxHighGiven) { newElectrode->ixHi = MESHlocate( xMeshList, card->ELCTxHigh ); } else { newElectrode->ixHi = ixMax; } if (newElectrode->ixLo > newElectrode->ixHi) { sprintf( ebuf, "electrode card %d has low x index (%d) > high x index (%d)", cardNum, newElectrode->ixLo, newElectrode->ixHi ); SPfrontEnd->IFerror( ERR_WARNING, ebuf, NULL ); error = E_PRIVATE; } if (card->ELCTiyLowGiven) { newElectrode->iyLo = MAX(card->ELCTiyLow, iyMin); } else if (card->ELCTyLowGiven) { newElectrode->iyLo = MESHlocate( yMeshList, card->ELCTyLow ); } else { newElectrode->iyLo = iyMin; } if (card->ELCTiyHighGiven) { newElectrode->iyHi = MIN(card->ELCTiyHigh, iyMax); } else if (card->ELCTyHighGiven) { newElectrode->iyHi = MESHlocate( yMeshList, card->ELCTyHigh ); } else { newElectrode->iyHi = iyMax; } if (newElectrode->iyLo > newElectrode->iyHi) { sprintf( ebuf, "electrode card %d has low y index (%d) > high y index (%d)", cardNum, newElectrode->iyLo, newElectrode->iyHi ); SPfrontEnd->IFerror( ERR_WARNING, ebuf, NULL ); error = E_PRIVATE; } } return( error ); }
void psht_make_weighted_healpix_geom_info (int nside, int stride, const double *weight, psht_geom_info **geom_info) { const double pi=3.141592653589793238462643383279502884197; ptrdiff_t npix=(ptrdiff_t)nside*nside*12; ptrdiff_t ncap=2*(ptrdiff_t)nside*(nside-1); int nrings=4*nside-1; double *theta=RALLOC(double,nrings); double *weight_=RALLOC(double,nrings); int *nph=RALLOC(int,nrings); double *phi0=RALLOC(double,nrings); ptrdiff_t *ofs=RALLOC(ptrdiff_t,nrings); int *stride_=RALLOC(int,nrings); int m; for (m=0; m<nrings; ++m) { int ring=m+1; ptrdiff_t northring = (ring>2*nside) ? 4*nside-ring : ring; stride_[m] = stride; if (northring < nside) { theta[m] = 2*asin(northring/(sqrt(6.)*nside)); nph[m] = 4*northring; phi0[m] = pi/nph[m]; ofs[m] = 2*northring*(northring-1)*stride; } else { double fact1 = (8.*nside)/npix; double costheta = (2*nside-northring)*fact1; theta[m] = acos(costheta); nph[m] = 4*nside; if ((northring-nside) & 1) phi0[m] = 0; else phi0[m] = pi/nph[m]; ofs[m] = (ncap + (northring-nside)*nph[m])*stride; } if (northring != ring) /* southern hemisphere */ { theta[m] = pi-theta[m]; ofs[m] = (npix - nph[m])*stride - ofs[m]; } weight_[m]=4.*pi/npix*weight[northring-1]; } #if 0 { double *w2=RALLOC(double,nrings); make_healpix_weights(nside,w2); for (m=0; m<nrings; ++m) weight_[m]*=w2[m]; DEALLOC(w2); } #endif psht_make_geom_info (nrings, nph, ofs, stride_, phi0, theta, weight_, geom_info); DEALLOC(theta); DEALLOC(weight_); DEALLOC(nph); DEALLOC(phi0); DEALLOC(ofs); DEALLOC(stride_); }
/* * Name: DOMNsetup * Purpose: convert a list of DOMNcard's to DOMNdomain's * Formals: cardList: list of cards to setup * domainList: returns the list of DOMNdomain's * xMeshList: list of coordinates in the x mesh * yMeshList: list of coordinates in the y mesh * Returns: OK/E_PRIVATE * Users: numerical devices * Calls: DOMNcheck */ int DOMNsetup(DOMNcard *cardList, DOMNdomain **domainList, MESHcoord *xMeshList, MESHcoord *yMeshList, MaterialInfo *materialList) { DOMNcard *card; DOMNdomain *newDomain = NULL; int ixMin, ixMax, iyMin, iyMax; int cardNum = 0; int error; char ebuf[512]; /* error message buffer */ /* Initialize list of domains */ *domainList = NULL; /* Check the card list */ if ((error = DOMNcheck( cardList, materialList )) != 0) return( error ); /* Find the limits on the indices */ MESHiBounds( xMeshList, &ixMin, &ixMax ); MESHiBounds( yMeshList, &iyMin, &iyMax ); error = OK; for ( card = cardList; card != NULL; card = card->DOMNnextCard ) { cardNum++; if (*domainList == NULL) { RALLOC( newDomain, DOMNdomain, 1 ); *domainList = newDomain; } else { RALLOC( newDomain->next, DOMNdomain, 1 ); newDomain = newDomain->next; } newDomain->id = card->DOMNnumber; newDomain->material = card->DOMNmaterial; newDomain->next = NULL; if (card->DOMNixLowGiven) { newDomain->ixLo = MAX(card->DOMNixLow, ixMin); } else if (card->DOMNxLowGiven) { newDomain->ixLo = MESHlocate( xMeshList, card->DOMNxLow ); } else { newDomain->ixLo = ixMin; } if (card->DOMNixHighGiven) { newDomain->ixHi = MIN(card->DOMNixHigh, ixMax); } else if (card->DOMNxHighGiven) { newDomain->ixHi = MESHlocate( xMeshList, card->DOMNxHigh ); } else { newDomain->ixHi = ixMax; } if (newDomain->ixLo > newDomain->ixHi) { sprintf( ebuf, "domain card %d has low x index (%d) > high x index (%d)", cardNum, newDomain->ixLo, newDomain->ixHi ); SPfrontEnd->IFerror( ERR_WARNING, ebuf, NULL ); error = E_PRIVATE; } if (card->DOMNiyLowGiven) { newDomain->iyLo = MAX(card->DOMNiyLow, iyMin); } else if (card->DOMNyLowGiven) { newDomain->iyLo = MESHlocate( yMeshList, card->DOMNyLow ); } else { newDomain->iyLo = iyMin; } if (card->DOMNiyHighGiven) { newDomain->iyHi = MIN(card->DOMNiyHigh, iyMax); } else if (card->DOMNyHighGiven) { newDomain->iyHi = MESHlocate( yMeshList, card->DOMNyHigh ); } else { newDomain->iyHi = iyMax; } if (newDomain->iyLo > newDomain->iyHi) { sprintf( ebuf, "domain card %d has low y index (%d) > high y index (%d)", cardNum, newDomain->iyLo, newDomain->iyHi ); SPfrontEnd->IFerror( ERR_WARNING, ebuf, NULL ); error = E_PRIVATE; } } return( error ); }
static void sharp_execute_job_mpi (sharp_job *job, MPI_Comm comm) { int ntasks; MPI_Comm_size(comm, &ntasks); if (ntasks==1) /* fall back to scalar implementation */ { sharp_execute_job (job); return; } MPI_Barrier(comm); double timer=wallTime(); job->opcnt=0; sharp_mpi_info minfo; sharp_make_mpi_info(comm, job, &minfo); if (minfo.npairtotal>minfo.ntasks*300) { int nsub=(minfo.npairtotal+minfo.ntasks*200-1)/(minfo.ntasks*200); for (int isub=0; isub<nsub; ++isub) { sharp_job ljob=*job; // When creating a_lm, every sub-job produces a complete set of // coefficients; they need to be added up. if ((isub>0)&&(job->type==SHARP_MAP2ALM)) ljob.flags|=SHARP_ADD; sharp_geom_info lginfo; lginfo.pair=RALLOC(sharp_ringpair,(job->ginfo->npairs/nsub)+1); lginfo.npairs=0; lginfo.nphmax = job->ginfo->nphmax; while (lginfo.npairs*nsub+isub<job->ginfo->npairs) { lginfo.pair[lginfo.npairs]=job->ginfo->pair[lginfo.npairs*nsub+isub]; ++lginfo.npairs; } ljob.ginfo=&lginfo; sharp_execute_job_mpi (&ljob,comm); job->opcnt+=ljob.opcnt; DEALLOC(lginfo.pair); } } else { int lmax = job->ainfo->lmax; job->norm_l = sharp_Ylmgen_get_norm (lmax, job->spin); /* clear output arrays if requested */ init_output (job); alloc_phase_mpi (job,job->ainfo->nm,job->ginfo->npairs,minfo.mmax+1, minfo.npairtotal); double *cth = RALLOC(double,minfo.npairtotal), *sth = RALLOC(double,minfo.npairtotal); int *mlim = RALLOC(int,minfo.npairtotal); for (int i=0; i<minfo.npairtotal; ++i) { cth[i] = cos(minfo.theta[i]); sth[i] = sin(minfo.theta[i]); mlim[i] = sharp_get_mlim(lmax, job->spin, sth[i], cth[i]); } /* map->phase where necessary */ map2phase (job, minfo.mmax, 0, job->ginfo->npairs); map2alm_comm (job, &minfo); #pragma omp parallel if ((job->flags&SHARP_NO_OPENMP)==0) { sharp_job ljob = *job; sharp_Ylmgen_C generator; sharp_Ylmgen_init (&generator,lmax,minfo.mmax,ljob.spin); alloc_almtmp(&ljob,lmax); #pragma omp for schedule(dynamic,1) for (int mi=0; mi<job->ainfo->nm; ++mi) { /* alm->alm_tmp where necessary */ alm2almtmp (&ljob, lmax, mi); /* inner conversion loop */ inner_loop (&ljob, minfo.ispair, cth, sth, 0, minfo.npairtotal, &generator, mi, mlim); /* alm_tmp->alm where necessary */ almtmp2alm (&ljob, lmax, mi); } sharp_Ylmgen_destroy(&generator); dealloc_almtmp(&ljob); #pragma omp critical job->opcnt+=ljob.opcnt; } /* end of parallel region */ alm2map_comm (job, &minfo); /* phase->map where necessary */ phase2map (job, minfo.mmax, 0, job->ginfo->npairs); DEALLOC(mlim); DEALLOC(cth); DEALLOC(sth); DEALLOC(job->norm_l); dealloc_phase (job); } sharp_destroy_mpi_info(&minfo); job->time=wallTime()-timer; }
static void hpsharp_make_healpix_geom_info_2 (int nside, double *wgt, double z1, double z2, hpsharp_geom_info **geom_info) { const double pi=3.141592653589793238462643383279502884197; ptrdiff_t npix=(ptrdiff_t)nside*nside*12; ptrdiff_t ncap=2*(ptrdiff_t)nside*(nside-1); int nrings=4*nside-1; double *theta=RALLOC(double,nrings); double *weight=RALLOC(double,nrings); int *nph=RALLOC(int,nrings); double *phi0=RALLOC(double,nrings); ptrdiff_t *ofs=RALLOC(ptrdiff_t,nrings); int *stride=RALLOC(int,nrings); int m=0,i; for (i=0; i<nrings; ++i) { int ring=i+1; ptrdiff_t northring = (ring>2*nside) ? 4*nside-ring : ring; if (northring < nside) { theta[m] = 2*asin(northring/(sqrt(6.)*nside)); nph[m] = 4*northring; phi0[m] = pi/nph[m]; ofs[m] = 2*northring*(northring-1); } else { double fact1 = (8.*nside)/npix; double costheta = (2*nside-northring)*fact1; theta[m] = acos(costheta); nph[m] = 4*nside; if ((northring-nside) & 1) phi0[m] = 0; else phi0[m] = pi/nph[m]; ofs[m] = ncap + (northring-nside)*nph[m]; } if (northring != ring) /* southern hemisphere */ { theta[m] = pi-theta[m]; ofs[m] = npix - nph[m] - ofs[m]; } weight[m]=4.*pi/npix*wgt[northring-1]; stride[m]=1; /* decide whether the ring must be used */ { double ctheta = cos(theta[m]); if (z1<z2) { if ((ctheta>z1) && (ctheta<z2)) ++m; } else { if ((ctheta>z1) || (ctheta<z2)) ++m; } } } hpsharp_make_geom_info (m, nph, ofs, stride, phi0, theta, weight, geom_info); DEALLOC(theta); DEALLOC(weight); DEALLOC(nph); DEALLOC(phi0); DEALLOC(ofs); DEALLOC(stride); }