void MoleculaB::centraentorno (int num) //Centra un atomo en su entorno de tres vecinos { pto3D pto = susatomos.get(num)->vert; int numvert = nvec (num); pto3D posnueva = pto3D (); if (numvert == 3) { for (int i = 0; i < susatomos.size (); i++) { pto3D ptov = susatomos.get(i)->vert; if (ptov.dista (pto) < 1.6) posnueva = posnueva.mas (ptov.escala (0.333)); } mueve (num, posnueva); } }
//*************************************************TERM 1************************************************* //brute force sum dcomplex Zetafunc::term1full(const double q2){ dcomplex result(0.,0.),tmpcomp; double fact,rsq,theta,phi; threevec<double> nvec,npar,nperp,rvec; double resultre=0.,resultim=0.; #pragma omp parallel for reduction(+:resultre) reduction(+:resultim) private(rvec,rsq,theta,phi,nvec,fact,tmpcomp,npar,nperp) for(int z=-MAXRUN; z<=MAXRUN; z++){ for(int y=-MAXRUN; y<=MAXRUN; y++){ for(int x=-MAXRUN; x<=MAXRUN; x++){ nvec(static_cast<double>(x),static_cast<double>(y),static_cast<double>(z)); //compute r: if(!is_zeroboost){ orthogonal_projection(nvec,boost,npar,nperp); rvec=npar/gamma-boost/(2.*gamma)+nperp; } else{ rvec=nvec; } rvec.get_spherical_coordinates(rsq,theta,phi); if(l!=0)fact=::std::pow(rsq,l); //compute |r|^l else fact=1.; rsq*=rsq; //compute r^2 //compute prefact: fact*=::std::exp(-lambda*(rsq-q2))/(rsq-q2); //compute the ratio tmpcomp=fact*spherical_harmonicy(l,m,theta,phi); //multiply with spherical harmonics resultre+=tmpcomp.re(); resultim+=tmpcomp.im(); //result+=tmpcomp; } } } result=dcomplex(resultre,resultim); return result; }
bool findAll(const char* text, nvec& vmatch) const{ size_t n = regex_->mark_count() + 1; vector<int> sm; for(size_t i = 0; i < n; ++i){ sm.push_back(i); } cregex_token_iterator itr(text, text + strlen(text), *regex_, sm); bool matched = false; cregex_token_iterator itrEnd; while(itr != itrEnd){ vmatch.push_back(nvec()); nvec& mi = vmatch.back(); for(size_t i = 0; i < n; ++i){ mi.push_back(itr->str()); ++itr; } matched = true; } return matched; }
///////////////////////////////////////////////////////////////////////////////// // calculate the intersection of a plane the given ray // the ray has an origin and a direction, ray = origin + t*direction // find the t parameter, return true if it is between 0.0 and 1.0, false // otherwise, write the results in following variables: // depth - t \in [0.0 1.0] // posX - x position of intersection point, nothing if no intersection // posY - y position of intersection point, nothing if no intersection // posZ - z position of intersection point, nothing if no intersection // normalX - x component of normal at intersection point, nothing if no intersection // normalX - y component of normal at intersection point, nothing if no intersection // normalX - z component of normal at intersection point, nothing if no intersection // ///////////////////////////////////////////////////////////////////////////////// bool Plane::intersect(Ray ray, double *depth, double *posX, double *posY, double *posZ, double *normalX, double *normalY, double *normalZ) { //////////*********** START OF CODE TO CHANGE *******//////////// Vec3 evec( ray.origin[0], ray.origin[1], ray.origin[2]); Vec3 nvec( this->params[0], this->params[1], this->params[2]); Vec3 dvec( ray.direction[0], ray.direction[1], ray.direction[2]); double d = this->params[3] * sqrt(nvec[0] * nvec[0] + nvec[1] * nvec[1] + nvec[2] * nvec[2]); double t = -1; double denom = dvec.dot(nvec); if (denom != 0) { t = (-d - (evec.dot(nvec))) / dvec.dot(nvec); } if (t <= 0) { return false; } else { *depth = t; *posX = (dvec[0] * t) + evec[0]; *posY = (dvec[1] * t) + evec[1]; *posZ = (dvec[2] * t) + evec[2]; if (denom > 0) { *normalX = -nvec[0]; *normalY = -nvec[1]; *normalZ = -nvec[2]; } else { *normalX = nvec[0]; *normalY = nvec[1]; *normalZ = nvec[2]; } } //////////*********** END OF CODE TO CHANGE *******//////////// //printf("dvec[0], dvec[1], dvec[2]: (%f, %f, %f) \n", dvec[0], dvec[1], dvec[2]); //printf("evec[0], evec[1], evec[2]: (%f, %f, %f) \n", evec[0], evec[1], evec[2]); //printf("Plane interesection at t:%f (%f, %f, %f)\n", t, *posX, *posY, *posZ); return true; }
struct Shade GetCR(double x, double y, double z) /* x,y,z in voxel space, w/o rotation */ { struct Shade cl; int x2; int y2; int z2; double Id, Ia, Kd, Ka, I; Vector3 vec(3); Vector3 nvec(3); double s, c; vec[0] = x; vec[1] = y; vec[2] = z; /* Translate to center */ vec -= vol_data.size() / 2.0; /* un-roate about x; */ s = sin_neg_y_ang; c = cos_neg_y_ang; nvec[0] = vec[0]; nvec[1] = vec[1] * c + vec[2] * s; nvec[2] = -vec[1] * s + vec[2] * c; vec[0] = nvec[0]; vec[1] = nvec[1]; vec[2] = nvec[2]; /* Unrotate about y */ s = sin_neg_x_ang; c = cos_neg_x_ang; nvec[0] = vec[0] * c - vec[2] * s; nvec[1] = vec[1]; nvec[2] = vec[0] * s + vec[2] * c; vec[0] = nvec[0]; vec[1] = nvec[1]; vec[2] = nvec[2]; /* Untranslate */ vec += vol_data.size() / 2.0; /*okay, now get the color and data information */ x2 = (int) vec[0]; y2 = (int) vec[1]; z2 = (int) vec[2]; if ((vec[0] - x2) >= 0.5) x2++; if ((vec[1] - y2) >= 0.5) y2++; if ((vec[2] - z2) >= 0.5) z2++; if (x2 >= vol_data.size_x() || x2 < 0 || y2 >= vol_data.size_y() || y2 < 0 || z2 >= vol_data.size_z() || z2 < 0) { cl.red = 0; cl.green = 0; cl.blue = 0; cl.alpha = 0; } else cl = GetColor(vol_data(x2,y2,z2)); if (Glighting) { int i, j, k; int xn[3], yn[3], zn[3], den; int xx, yy, zz; for (i = 0; i <= 2; i++) { j = x2 - 1 + i; j = std::max(j, 0); j = std::min(j, vol_data.size_x() - 1); xn[i] = j; j = y2 - 1 + i; j = std::max(j, 0); j = std::min(j, vol_data.size_y() - 1); yn[i] = j; j = z2 - 1 + i; j = std::max(j, 0); j = std::min(j, vol_data.size_z() - 1); zn[i] = j; } nvec[0] = 0; nvec[1] = 0; nvec[2] = 0; for (i = 0; i <= 2; i++) { xx = i - 1; for (j = 0; j <= 2; j++) { yy = j - 1; for (k = 0; k <= 2; k++) { if (i == 1 && j == 1 && k == 1) continue; zz = k - 1; den = GetDen(vol_data(xn[i],yn[j],zn[k])); nvec[0] += xx * den; nvec[1] += yy * den; nvec[2] += zz * den; } } } #if 0 x1=std::max(x2-1,0); y1=std::max(y2-1,0); z1=std::max(z2-1,0); x3=std::min(x2+1,x_size-1); y3=std::min(y2+1,vol_data.size_y()-1); z3=std::min(z2+1,z_size-1); nvec[0]=GetDen(GETDATA(x3,y2,z2))-GetDen(GETDATA(x1,y2,z2)); nvec[1]=GetDen(GETDATA(x2,y3,z2))-GetDen(GETDATA(x2,y1,z2)); nvec[2]=GetDen(GETDATA(x2,y2,z3))-GetDen(GETDATA(x2,y2,z1)); #endif normalize(nvec); /* Define these !!*/ Kd = 0.8; Ka = 0.4; I = dot_prod(nvec, nvec); if (I == 0) { cl.alpha = 0; return cl; } Id = Kd * (dot_prod(lvect, nvec)); if (Id < 0) Id = 0; Ia = Ka; I = Id + Ia; if (I > 1) I = 1.0; cl.red *= I; cl.green *= I; cl.blue *= I; } return cl; }
// Right-hand side of the Lax-Wendroff discretization: // // ( q(t+dt) - q(t) )/dt = -F_{x} - G_{y}. // // This routine constructs the 'time-integrated' flux functions F and G using the // Cauchy-Kowalewski procedure. // // First, consider time derivatives of q // // q^{n+1} = q^n + dt * (q^n_t + dt/2 * q^n_tt + dt^3/6 q^n_ttt ). // // Formally, these are given by // // q_{t} = ( -f(q) )_x + ( -g(q) )_y, // q_{tt} = ( f'(q) * ( f_x + g_y )_x + ( g'(q) * ( f_x + g_y )_y // q_{ttt} = ... // // Now, considering Taylor expansions of f and g, centered about t = t^n // // F = f^n + (t-t^n) \dot{f^n} + \cdots // G = g^n + (t-t^n) \dot{g^n} + \cdots // // We have the following form, after integrating in time // // F: = ( f - dt/2 * ( f'(q)*( f_x+g_y ) // + dt^2/6 ( \pd2{f}{q} \cdot (f_x+g_y,f_x+g_y) + // \pd{f}{q} ( f_x + g_y )_t ) + \cdots // // G: = ( g - dt/2 * ( g'(q)*( f_x+g_y ) // + dt^2/6 ( \pd2{g}{q} \cdot (f_x+g_y,f_x+g_y) + // \pd{g}{q} ( f_x + g_y )_t ) + \cdots // // where the final ingredient is // // (f_x+g_y)_t = \pd2{f}{q} \cdot (q_x, f_x+g_y ) + \pd{f}{q} ( f_xx + g_xy ) + // \pd2{g}{q} \cdot (q_y, f_x+g_y ) + \pd{g}{q} ( f_xy + g_yy ). // // At the end of the day, we set // // L(q) := -F_x - G_y. // // See also: ConstructL. void LaxWendroff(double dt, const dTensorBC4& aux, const dTensorBC4& q, // set bndy values modifies these dTensorBC4& Lstar, dTensorBC3& smax) { printf("This call hasn't been tested \n"); if ( !dogParams.get_flux_term() ) { return; } const edge_data& edgeData = Legendre2d::get_edgeData(); const int space_order = dogParams.get_space_order(); const int mx = q.getsize(1); const int my = q.getsize(2); const int meqn = q.getsize(3); const int kmax = q.getsize(4); const int mbc = q.getmbc(); const int maux = aux.getsize(3); // Flux values // // Space-order = number of quadrature points needed for 1D integration // along cell edges. // dTensorBC4 Fm(mx, my, meqn, space_order, mbc); dTensorBC4 Fp(mx, my, meqn, space_order, mbc); dTensorBC4 Gm(mx, my, meqn, space_order, mbc); dTensorBC4 Gp(mx, my, meqn, space_order, mbc); // Flux function void FluxFunc(const dTensor2& xpts, const dTensor2& Q, const dTensor2& Aux, dTensor3& flux); // Jacobian of the flux function: void DFluxFunc(const dTensor2& xpts, const dTensor2& Q, const dTensor2& Aux, dTensor4& Dflux ); // Hessian of the flux function: void D2FluxFunc(const dTensor2& xpts, const dTensor2& Q, const dTensor2& Aux, dTensor5& D2flux ); // Riemann solver that relies on the fact that we already have // f(ql) and f(qr) already computed: double RiemannSolveLxW(const dTensor1& nvec, const dTensor1& xedge, const dTensor1& Ql, const dTensor1& Qr, const dTensor1& Auxl, const dTensor1& Auxr, const dTensor1& ffl, const dTensor1& ffr, dTensor1& Fl, dTensor1& Fr); void LstarExtra(const dTensorBC4*, const dTensorBC4*, dTensorBC4*); void ArtificialViscosity(const dTensorBC4* aux, const dTensorBC4* q, dTensorBC4* Lstar); // Grid information const double xlower = dogParamsCart2.get_xlow(); const double ylower = dogParamsCart2.get_ylow(); const double dx = dogParamsCart2.get_dx(); const double dy = dogParamsCart2.get_dy(); // --------------------------------------------------------------------- // // Boundary data: // --------------------------------------------------------------------- // // TODO - call this routine before calling this function. // void SetBndValues(dTensorBC4& q, dTensorBC4& aux); // SetBndValues(q, aux); // --------------------------------------------------------- // --------------------------------------------------------------------- // // Part 0: Compute the Lax-Wendroff "flux" function: // // Here, we include the extra information about time derivatives. // --------------------------------------------------------------------- // dTensorBC4 F(mx, my, meqn, kmax, mbc); F.setall(0.); dTensorBC4 G(mx, my, meqn, kmax, mbc); G.setall(0.); void L2ProjectLxW( const int mterms, const double alpha, const double beta_dt, const double charlie_dt, const int istart, const int iend, const int jstart, const int jend, const int QuadOrder, const int BasisOrder_auxin, const int BasisOrder_fout, const dTensorBC4* qin, const dTensorBC4* auxin, dTensorBC4* F, dTensorBC4* G, void FluxFunc (const dTensor2& xpts, const dTensor2& Q, const dTensor2& Aux, dTensor3& flux), void DFluxFunc (const dTensor2& xpts, const dTensor2& Q, const dTensor2& aux, dTensor4& Dflux), void D2FluxFunc (const dTensor2& xpts, const dTensor2& Q, const dTensor2& aux, dTensor5& D2flux) ); printf("hello\n"); L2ProjectLxW( 3, 1.0, 0.5*dt, dt*dt/6.0, 1-mbc, mx+mbc, 1-mbc, my+mbc, space_order, space_order, space_order, &q, &aux, &F, &G, &FluxFunc, &DFluxFunc, D2FluxFunc ); // --------------------------------------------------------- // Part I: compute source term // --------------------------------------------------------- if( dogParams.get_source_term() > 0 ) { // eprintf("error: have not implemented source term for LxW solver."); printf("Source term has not been implemented for LxW solver. Terminating program."); exit(1); } Lstar.setall( 0. ); // --------------------------------------------------------- // Part II: compute inter-element interaction fluxes // // N = int( F(q,x,t) * phi_x, x ) / dA // // --------------------------------------------------------- // 1-direction: loop over interior edges and solve Riemann problems dTensor1 nvec(2); nvec.set(1, 1.0e0 ); nvec.set(2, 0.0e0 ); #pragma omp parallel for for (int i=(2-mbc); i<=(mx+mbc); i++) { dTensor1 Ql(meqn), Qr(meqn); dTensor1 ffl(meqn), ffr(meqn); dTensor1 Fl(meqn), Fr(meqn); dTensor1 DFl(meqn), DFr(meqn); dTensor1 Auxl(maux), Auxr(maux); dTensor1 xedge(2); for (int j=(2-mbc); j<=(my+mbc-1); j++) { // ell indexes Riemann point along the edge for (int ell=1; ell<=space_order; ell++) { // Riemann data - q and f (from basis functions/q) for (int m=1; m<=meqn; m++) { Ql.set (m, 0.0 ); Qr.set (m, 0.0 ); ffl.set(m, 0.0 ); ffr.set(m, 0.0 ); for (int k=1; k<=kmax; k++) { // phi_xl( xi=1.0, eta ), phi_xr( xi=-1.0, eta ) Ql.fetch(m) += edgeData.phi_xl->get(ell,k)*q.get(i-1, j, m, k ); Qr.fetch(m) += edgeData.phi_xr->get(ell,k)*q.get(i, j, m, k ); ffl.fetch(m) += edgeData.phi_xl->get(ell,k)*F.get(i-1, j, m, k ); ffr.fetch(m) += edgeData.phi_xr->get(ell,k)*F.get(i, j, m, k ); } } // Riemann data - aux for (int m=1; m<=maux; m++) { Auxl.set(m, 0.0 ); Auxr.set(m, 0.0 ); for (int k=1; k<=kmax; k++) { Auxl.fetch(m) += edgeData.phi_xl->get(ell,k)*aux.get(i-1, j, m, k); Auxr.fetch(m) += edgeData.phi_xr->get(ell,k)*aux.get(i, j, m, k); } } // Solve Riemann problem xedge.set(1, xlower + (double(i)-1.0)*dx ); xedge.set(2, ylower + (double(j)-0.5)*dy ); const double smax_edge = RiemannSolveLxW( nvec, xedge, Ql, Qr, Auxl, Auxr, ffl, ffr, Fl, Fr); smax.set(i-1, j, 1, Max(dy*smax_edge,smax.get(i-1, j, 1)) ); smax.set(i, j, 1, Max(dy*smax_edge,smax.get(i, j, 1)) ); // Construct fluxes for (int m=1; m<=meqn; m++) { Fm.set(i , j, m, ell, Fr.get(m) ); Fp.set(i-1, j, m, ell, Fl.get(m) ); } } } } // 2-direction: loop over interior edges and solve Riemann problems nvec.set(1, 0.0e0 ); nvec.set(2, 1.0e0 ); #pragma omp parallel for for (int i=(2-mbc); i<=(mx+mbc-1); i++) { dTensor1 Ql(meqn), Qr(meqn); dTensor1 Fl(meqn), Fr(meqn); dTensor1 ffl(meqn), ffr(meqn); dTensor1 Auxl(maux),Auxr(maux); dTensor1 xedge(2); for (int j=(2-mbc); j<=(my+mbc); j++) for (int ell=1; ell<=space_order; ell++) { // Riemann data - q for (int m=1; m<=meqn; m++) { Ql.set (m, 0.0 ); Qr.set (m, 0.0 ); ffl.set (m, 0.0 ); ffr.set (m, 0.0 ); for (int k=1; k<=kmax; k++) { Ql.fetch(m) += edgeData.phi_yl->get(ell, k)*q.get(i, j-1, m, k ); Qr.fetch(m) += edgeData.phi_yr->get(ell, k)*q.get(i, j, m, k ); ffl.fetch(m) += edgeData.phi_yl->get(ell, k)*G.get(i, j-1, m, k ); ffr.fetch(m) += edgeData.phi_yr->get(ell, k)*G.get(i, j, m, k ); } } // Riemann data - aux for (int m=1; m<=maux; m++) { Auxl.set(m, 0.0 ); Auxr.set(m, 0.0 ); for (int k=1; k<=kmax; k++) { Auxl.fetch(m) += edgeData.phi_yl->get(ell,k)*aux.get(i,j-1,m,k); Auxr.fetch(m) += edgeData.phi_yr->get(ell,k)*aux.get(i,j,m,k); } } // Solve Riemann problem xedge.set(1, xlower + (double(i)-0.5)*dx ); xedge.set(2, ylower + (double(j)-1.0)*dy ); const double smax_edge = RiemannSolveLxW( nvec, xedge, Ql, Qr, Auxl, Auxr, ffl, ffr, Fl, Fr); smax.set(i, j-1, 2, Max(dx*smax_edge, smax.get(i, j-1, 2)) ); smax.set(i, j, 2, Max(dx*smax_edge, smax.get(i, j, 2)) ); // Construct fluxes for (int m=1; m<=meqn; m++) { Gm.set(i, j, m, ell, Fr.get(m) ); Gp.set(i, j-1, m, ell, Fl.get(m) ); } } } // Compute ``flux differences'' dF and dG const double half_dx_inv = 0.5/dx; const double half_dy_inv = 0.5/dy; const int mlength = Lstar.getsize(3); assert_eq( meqn, mlength ); // Use the four values, Gm, Gp, Fm, Fp to construct the boundary integral: #pragma omp parallel for for (int i=(2-mbc); i<=(mx+mbc-1); i++) for (int j=(2-mbc); j<=(my+mbc-1); j++) for (int m=1; m<=mlength; m++) for (int k=1; k<=kmax; k++) { // 1-direction: dF double F1 = 0.0; double F2 = 0.0; for (int ell=1; ell<=space_order; ell++) { F1 = F1 + edgeData.wght_phi_xr->get(ell,k)*Fm.get(i,j,m,ell); F2 = F2 + edgeData.wght_phi_xl->get(ell,k)*Fp.get(i,j,m,ell); } // 2-direction: dG double G1 = 0.0; double G2 = 0.0; for (int ell=1; ell<=space_order; ell++) { G1 = G1 + edgeData.wght_phi_yr->get(ell,k)*Gm.get(i,j,m,ell); G2 = G2 + edgeData.wght_phi_yl->get(ell,k)*Gp.get(i,j,m,ell); } Lstar.fetch(i,j,m,k) -= (half_dx_inv*(F2-F1) + half_dy_inv*(G2-G1)); } // --------------------------------------------------------- // --------------------------------------------------------- // Part III: compute intra-element contributions // --------------------------------------------------------- // No need to call this if first-order in space if(dogParams.get_space_order()>1) { dTensorBC4 Ltmp( mx, my, meqn, kmax, mbc ); void L2ProjectGradAddLegendre(const int istart, const int iend, const int jstart, const int jend, const int QuadOrder, const dTensorBC4* F, const dTensorBC4* G, dTensorBC4* fout ); L2ProjectGradAddLegendre( 1-mbc, mx+mbc, 1-mbc, my+mbc, space_order, &F, &G, &Lstar ); } // --------------------------------------------------------- // --------------------------------------------------------- // Part IV: add extra contributions to Lstar // --------------------------------------------------------- // Call LstarExtra LstarExtra(&q,&aux,&Lstar); // --------------------------------------------------------- // --------------------------------------------------------- // Part V: artificial viscosity limiter // --------------------------------------------------------- if (dogParams.get_space_order()>1 && dogParams.using_viscosity_limiter()) { ArtificialViscosity(&aux,&q,&Lstar); } // --------------------------------------------------------- }
//can be used if boost is zero: dcomplex Zetafunc::term1noboost(const double q2){ dcomplex result(0.,0.),sphfact,tmpcomp; double fact,rsq,r,theta,phi,resultre,resultim; threevec<double> nvec; //zero term is zero: result=dcomplex(0.,0.); //line terms //x>0, y=z=0 and y>0, x=z=0 and z>0, x=y=0: //note that z->-z is equivalent to theta->pi-theta, similar to this: x->-x yields phi->pi-phi and y->-y is phi->2pi-phi sphfact= spherical_harmonicy(l,m,pimath/2. , 0.); //x>0 sphfact+= spherical_harmonicy(l,m,pimath/2. , pimath); //x<0 sphfact+= spherical_harmonicy(l,m,pimath/2. , pimath/2.); //y>0 sphfact+= spherical_harmonicy(l,m,pimath/2. , 3.*pimath/2.); //y<0 sphfact+= spherical_harmonicy(l,m,0. , 0.); //z>0 sphfact+= spherical_harmonicy(l,m,pimath , 0.); //z<0 //reduce resultre=0.,resultim=0.; #pragma omp parallel for reduction(+:resultre) reduction(+:resultim) firstprivate(q2,sphfact) private(rsq,r,tmpcomp) schedule(static) for(int x=1; x<=MAXRUN; x++){ rsq=x*x; tmpcomp=dcomplex(::std::exp(-lambda*(rsq-q2))*::std::pow(static_cast<double>(x),l)/(rsq-q2),0.)*sphfact; resultre+=tmpcomp.re(); resultim+=tmpcomp.im(); } result+=dcomplex(resultre,resultim); //plane terms //x,y!>0, z=0: //the four ylm account for the possibilities +/+, +/-, -/+, -/-: resultre=0.,resultim=0.; #pragma omp parallel for reduction(+:resultre) reduction(+:resultim) firstprivate(q2) private(rsq,r,theta,phi,sphfact,tmpcomp) schedule(static) for(int y=1; y<=MAXRUN; y++){ for(int x=1; x<=MAXRUN; x++){ threevec<int>(x,y,0).get_spherical_coordinates(r,theta,phi); rsq=r*r; //z=0: sphfact= spherical_harmonicy(l,m,theta , phi); //x,y>0 sphfact+= spherical_harmonicy(l,m,theta , pimath-phi); //x<0,y>0 sphfact+= spherical_harmonicy(l,m,theta , pimath+phi); //x,y<0 sphfact+= spherical_harmonicy(l,m,theta , 2.*pimath-phi); //x>0,y<0 //result tmpcomp=dcomplex(::std::exp(-lambda*(rsq-q2))*::std::pow(r,l)/(rsq-q2),0.)*sphfact; resultre+=tmpcomp.re(); resultim+=tmpcomp.im(); } } result+=dcomplex(resultre,resultim); //x,z>0, y=0 and y,z>0, x=0: resultre=0.,resultim=0.; #pragma omp parallel for reduction(+:resultre) reduction(+:resultim) firstprivate(q2) private(rsq,r,theta,phi,sphfact,tmpcomp) schedule(static) for(int z=1; z<=MAXRUN; z++){ for(int x=1; x<=MAXRUN; x++){ threevec<int>(x,0,z).get_spherical_coordinates(r,theta,phi); rsq=r*r; //y=0: sphfact= spherical_harmonicy(l,m,theta , 0); //x,z>0 sphfact+= spherical_harmonicy(l,m,pimath-theta , 0); //x>0,z<0 sphfact+= spherical_harmonicy(l,m,theta , pimath); //x<0,z>0 sphfact+= spherical_harmonicy(l,m,pimath-theta , pimath); //x,z<0 //x=0: sphfact+= spherical_harmonicy(l,m,theta , pimath/2.); //y,z>0 sphfact+= spherical_harmonicy(l,m,pimath-theta , pimath/2.); //y>0,z<0 sphfact+= spherical_harmonicy(l,m,theta , 3.*pimath/2.); //y<0,z>0 sphfact+= spherical_harmonicy(l,m,pimath-theta , 3.*pimath/2.); //y,z<0 //result: tmpcomp=dcomplex(::std::exp(-lambda*(rsq-q2))*::std::pow(r,l)/(rsq-q2),0.)*sphfact; resultre+=tmpcomp.re(); resultim+=tmpcomp.im(); } } result+=dcomplex(resultre,resultim); //cubic terms //x,y,z>0 resultre=0., resultim=0.; #pragma omp parallel for reduction(+:resultre) reduction(+:resultim) firstprivate(q2) private(nvec,rsq,r,theta,phi,fact,tmpcomp) schedule(static) for(int z=1; z<=MAXRUN; z++){ for(int y=1; y<=MAXRUN; y++){ for(int x=1; x<=MAXRUN; x++){ nvec(static_cast<double>(x),static_cast<double>(y),static_cast<double>(z)); nvec.get_spherical_coordinates(r,theta,phi); fact=::std::pow(r,l); //compute |r|^l rsq=r*r; //compute r^2 fact*=::std::exp(-lambda*(rsq-q2))/(rsq-q2); //compute the ratio //compute sphfact: account for all possible orientations sphfact=dcomplex(0.,0.); for(unsigned int thetaa=0; thetaa<2; thetaa++){ sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,phi); //x,y>0 sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,pimath-phi); //x<0,y>0 sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,pimath+phi); //x,y<0 sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,2.*pimath-phi); //x>0,y<0 } //compute the result: tmpcomp=fact*sphfact; //ratio * ylm factor resultre+=tmpcomp.re(); resultim+=tmpcomp.im(); } } } result+=dcomplex(resultre,resultim); return result; }