Cache wave extraction angular kernels
(cherry picked from commit e4c25eb21f)
This commit is contained in:
@@ -36,7 +36,14 @@ using namespace std;
|
||||
//| Constructor
|
||||
//|============================================================================
|
||||
|
||||
surface_integral::surface_integral(int iSymmetry) : Symmetry(iSymmetry)
|
||||
surface_integral::surface_integral(int iSymmetry) : Symmetry(iSymmetry),
|
||||
wave_cache_spinw(-1),
|
||||
wave_cache_maxl(-1),
|
||||
wave_cache_modes(0),
|
||||
wave_theta_pos(0),
|
||||
wave_theta_neg(0),
|
||||
wave_phi_cos(0),
|
||||
wave_phi_sin(0)
|
||||
{
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &cpusize);
|
||||
@@ -182,6 +189,7 @@ surface_integral::surface_integral(int iSymmetry) : Symmetry(iSymmetry)
|
||||
//|============================================================================
|
||||
surface_integral::~surface_integral()
|
||||
{
|
||||
clear_wave_cache();
|
||||
delete[] nx_g;
|
||||
delete[] ny_g;
|
||||
delete[] nz_g;
|
||||
@@ -190,6 +198,65 @@ surface_integral::~surface_integral()
|
||||
delete[] wtcostheta;
|
||||
#endif
|
||||
}
|
||||
void surface_integral::clear_wave_cache()
|
||||
{
|
||||
delete[] wave_theta_pos;
|
||||
delete[] wave_theta_neg;
|
||||
delete[] wave_phi_cos;
|
||||
delete[] wave_phi_sin;
|
||||
wave_theta_pos = 0;
|
||||
wave_theta_neg = 0;
|
||||
wave_phi_cos = 0;
|
||||
wave_phi_sin = 0;
|
||||
wave_cache_spinw = -1;
|
||||
wave_cache_maxl = -1;
|
||||
wave_cache_modes = 0;
|
||||
}
|
||||
void surface_integral::build_wave_cache(int spinw, int maxl)
|
||||
{
|
||||
if (wave_cache_spinw == spinw && wave_cache_maxl == maxl && wave_theta_pos && wave_theta_neg && wave_phi_cos && wave_phi_sin)
|
||||
return;
|
||||
|
||||
clear_wave_cache();
|
||||
|
||||
int modes = 0;
|
||||
for (int pl = spinw; pl < maxl + 1; pl++)
|
||||
for (int pm = -pl; pm < pl + 1; pm++)
|
||||
modes++;
|
||||
|
||||
wave_theta_pos = new double[modes * N_theta];
|
||||
wave_theta_neg = new double[modes * N_theta];
|
||||
wave_phi_cos = new double[modes * N_phi];
|
||||
wave_phi_sin = new double[modes * N_phi];
|
||||
|
||||
int countlm = 0;
|
||||
for (int pl = spinw; pl < maxl + 1; pl++)
|
||||
for (int pm = -pl; pm < pl + 1; pm++)
|
||||
{
|
||||
const double prefactor = sqrt((2 * pl + 1.0) / 4.0 / PI);
|
||||
for (int i = 0; i < N_theta; i++)
|
||||
{
|
||||
#ifdef GaussInt
|
||||
const double weight = wtcostheta[i];
|
||||
#else
|
||||
const double weight = 1.0;
|
||||
#endif
|
||||
wave_theta_pos[countlm * N_theta + i] = prefactor * misc::Wigner_d_function(pl, pm, spinw, arcostheta[i]) * weight;
|
||||
wave_theta_neg[countlm * N_theta + i] = prefactor * misc::Wigner_d_function(pl, pm, spinw, -arcostheta[i]) * weight;
|
||||
}
|
||||
for (int j = 0; j < N_phi; j++)
|
||||
{
|
||||
const double phase = pm * (j + 0.5) * dphi;
|
||||
wave_phi_cos[countlm * N_phi + j] = cos(phase);
|
||||
wave_phi_sin[countlm * N_phi + j] = sin(phase);
|
||||
}
|
||||
countlm++;
|
||||
}
|
||||
|
||||
wave_cache_spinw = spinw;
|
||||
wave_cache_maxl = maxl;
|
||||
wave_cache_modes = modes;
|
||||
}
|
||||
//|----------------------------------------------------------------
|
||||
// spin weighted spinw component of psi4, general routine
|
||||
// l takes from spinw to maxl; m takes from -l to l
|
||||
@@ -264,6 +331,39 @@ void surface_integral::surf_Wave(double rex, int lev, cgh *GH, var *Rpsi4, var *
|
||||
lpsy = 8;
|
||||
|
||||
double psi4RR, psi4II;
|
||||
if (Symmetry == 0 || Symmetry == 1)
|
||||
{
|
||||
build_wave_cache(spinw, maxl);
|
||||
for (n = Nmin; n <= Nmax; n++)
|
||||
{
|
||||
i = int(n / N_phi);
|
||||
j = n - i * N_phi;
|
||||
|
||||
const double psi4RR0 = shellf[InList * n];
|
||||
const double psi4II0 = shellf[InList * n + 1];
|
||||
const double psi4RR1 = Rpsi4->SoA[2] * psi4RR0;
|
||||
const double psi4II1 = Ipsi4->SoA[2] * psi4II0;
|
||||
for (int countlm = 0; countlm < wave_cache_modes; countlm++)
|
||||
{
|
||||
const int theta_idx = countlm * N_theta + i;
|
||||
const int phi_idx = countlm * N_phi + j;
|
||||
const double theta_pos = wave_theta_pos[theta_idx];
|
||||
const double cosmphi_here = wave_phi_cos[phi_idx];
|
||||
const double sinmphi_here = wave_phi_sin[phi_idx];
|
||||
|
||||
RP_out[countlm] += theta_pos * (psi4RR0 * cosmphi_here + psi4II0 * sinmphi_here);
|
||||
IP_out[countlm] += theta_pos * (psi4II0 * cosmphi_here - psi4RR0 * sinmphi_here);
|
||||
if (Symmetry == 1)
|
||||
{
|
||||
const double theta_neg = wave_theta_neg[theta_idx];
|
||||
RP_out[countlm] += theta_neg * (psi4RR1 * cosmphi_here + psi4II1 * sinmphi_here);
|
||||
IP_out[countlm] += theta_neg * (psi4II1 * cosmphi_here - psi4RR1 * sinmphi_here);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (n = Nmin; n <= Nmax; n++)
|
||||
{
|
||||
// need round off always
|
||||
@@ -348,6 +448,7 @@ void surface_integral::surf_Wave(double rex, int lev, cgh *GH, var *Rpsi4, var *
|
||||
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < NN; ii++)
|
||||
{
|
||||
@@ -466,6 +567,39 @@ void surface_integral::surf_Wave(double rex, int lev, cgh *GH, var *Rpsi4, var *
|
||||
lpsy = 8;
|
||||
|
||||
double psi4RR, psi4II;
|
||||
if (Symmetry == 0 || Symmetry == 1)
|
||||
{
|
||||
build_wave_cache(spinw, maxl);
|
||||
for (n = Nmin; n <= Nmax; n++)
|
||||
{
|
||||
i = int(n / N_phi);
|
||||
j = n - i * N_phi;
|
||||
|
||||
const double psi4RR0 = shellf[InList * n];
|
||||
const double psi4II0 = shellf[InList * n + 1];
|
||||
const double psi4RR1 = Rpsi4->SoA[2] * psi4RR0;
|
||||
const double psi4II1 = Ipsi4->SoA[2] * psi4II0;
|
||||
for (int countlm = 0; countlm < wave_cache_modes; countlm++)
|
||||
{
|
||||
const int theta_idx = countlm * N_theta + i;
|
||||
const int phi_idx = countlm * N_phi + j;
|
||||
const double theta_pos = wave_theta_pos[theta_idx];
|
||||
const double cosmphi_here = wave_phi_cos[phi_idx];
|
||||
const double sinmphi_here = wave_phi_sin[phi_idx];
|
||||
|
||||
RP_out[countlm] += theta_pos * (psi4RR0 * cosmphi_here + psi4II0 * sinmphi_here);
|
||||
IP_out[countlm] += theta_pos * (psi4II0 * cosmphi_here - psi4RR0 * sinmphi_here);
|
||||
if (Symmetry == 1)
|
||||
{
|
||||
const double theta_neg = wave_theta_neg[theta_idx];
|
||||
RP_out[countlm] += theta_neg * (psi4RR1 * cosmphi_here + psi4II1 * sinmphi_here);
|
||||
IP_out[countlm] += theta_neg * (psi4II1 * cosmphi_here - psi4RR1 * sinmphi_here);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (n = Nmin; n <= Nmax; n++)
|
||||
{
|
||||
// need round off always
|
||||
@@ -550,6 +684,7 @@ void surface_integral::surf_Wave(double rex, int lev, cgh *GH, var *Rpsi4, var *
|
||||
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < NN; ii++)
|
||||
{
|
||||
|
||||
@@ -36,6 +36,11 @@ private:
|
||||
|
||||
double *nx_g, *ny_g, *nz_g; // global list of unit normals
|
||||
int myrank, cpusize;
|
||||
int wave_cache_spinw, wave_cache_maxl, wave_cache_modes;
|
||||
double *wave_theta_pos, *wave_theta_neg;
|
||||
double *wave_phi_cos, *wave_phi_sin;
|
||||
void clear_wave_cache();
|
||||
void build_wave_cache(int spinw, int maxl);
|
||||
|
||||
public:
|
||||
surface_integral(int iSymmetry);
|
||||
|
||||
Reference in New Issue
Block a user