3753 lines
126 KiB
C
3753 lines
126 KiB
C
|
|
//----------------------------------------------------------------
|
|
// Using Gauss-Legendre quadrature in theta direction
|
|
// and trapezoidal rule in phi direction (from Second Euler-Maclaurin summation formula, we can see that
|
|
// this method gives expolential convergence for periodic function)
|
|
//----------------------------------------------------------------
|
|
#ifdef newc
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <fstream>
|
|
#include <strstream>
|
|
#include <cmath>
|
|
#include <map>
|
|
using namespace std;
|
|
#else
|
|
#include <iostream.h>
|
|
#include <iomanip.h>
|
|
#include <fstream.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <map.h>
|
|
#endif
|
|
#include <mpi.h>
|
|
|
|
#include "misc.h"
|
|
#include "cgh.h"
|
|
#include "Parallel.h"
|
|
#include "surface_integral.h"
|
|
#include "fadmquantites_bssn.h"
|
|
#include "getnpem2.h"
|
|
#include "getnp4.h"
|
|
#include "parameters.h"
|
|
|
|
#define PI M_PI
|
|
//|============================================================================
|
|
//| Constructor
|
|
//|============================================================================
|
|
|
|
surface_integral::surface_integral(int iSymmetry) : Symmetry(iSymmetry)
|
|
{
|
|
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
|
|
MPI_Comm_size(MPI_COMM_WORLD, &cpusize);
|
|
int N = 40;
|
|
// read parameter from file
|
|
{
|
|
const int LEN = 256;
|
|
char pline[LEN];
|
|
string str, sgrp, skey, sval;
|
|
int sind;
|
|
char pname[50];
|
|
{
|
|
map<string, string>::iterator iter = parameters::str_par.find("inputpar");
|
|
if (iter != parameters::str_par.end())
|
|
{
|
|
strcpy(pname, (iter->second).c_str());
|
|
}
|
|
else
|
|
{
|
|
cout << "Error inputpar" << endl;
|
|
exit(0);
|
|
}
|
|
}
|
|
ifstream inf(pname, ifstream::in);
|
|
if (!inf.good() && myrank == 0)
|
|
{
|
|
cout << "Can not open parameter file " << pname << endl;
|
|
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
}
|
|
|
|
for (int i = 1; inf.good(); i++)
|
|
{
|
|
inf.getline(pline, LEN);
|
|
str = pline;
|
|
|
|
int status = misc::parse_parts(str, sgrp, skey, sval, sind);
|
|
if (status == -1)
|
|
{
|
|
cout << "error reading parameter file " << pname << " in line " << i << endl;
|
|
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
}
|
|
else if (status == 0)
|
|
continue;
|
|
|
|
if (sgrp == "SurfaceIntegral")
|
|
{
|
|
if (skey == "number of points for quarter sphere")
|
|
N = atoi(sval.c_str());
|
|
}
|
|
}
|
|
inf.close();
|
|
}
|
|
//|-----number of points for whole [0,pi] x [0,2pi]
|
|
N_phi = 4 * N; // for simplicity, we require this number must be 4*N
|
|
N_theta = 2 * N; // 2*N
|
|
|
|
if (myrank == 0)
|
|
{
|
|
cout << "-----------------------------------------------------------------------" << endl;
|
|
#ifdef GaussInt
|
|
cout << " spherical integration for wave form extraction with Gauss method " << endl;
|
|
#else
|
|
cout << " spherical integration for wave form extraction with mid point method " << endl;
|
|
#endif
|
|
cout << " N_phi = " << N_phi << endl;
|
|
cout << " N_theta = " << N_theta << endl;
|
|
cout << "-----------------------------------------------------------------------" << endl;
|
|
}
|
|
|
|
#ifdef GaussInt
|
|
// weight function cover all of [0,pi]
|
|
arcostheta = new double[N_theta];
|
|
wtcostheta = new double[N_theta];
|
|
|
|
// note: theta in [0,pi/2], upper half sphere, corresponds to 1 < costheta < 0
|
|
misc::gaulegf(-1.0, 1.0, arcostheta, wtcostheta, N_theta);
|
|
// due to symmetry, I need first half array corresponds to upper sphere, note these two arrays must match each other
|
|
misc::inversearray(arcostheta, N_theta);
|
|
misc::inversearray(wtcostheta, N_theta);
|
|
#endif
|
|
|
|
if (Symmetry == 2)
|
|
{
|
|
N_phi = N_phi / 4;
|
|
N_theta = N_theta / 2;
|
|
dphi = PI / (2.0 * N_phi);
|
|
dcostheta = 1.0 / N_theta;
|
|
factor = 8;
|
|
}
|
|
else if (Symmetry == 1)
|
|
{
|
|
N_theta = N_theta / 2;
|
|
dphi = 2.0 * PI / N_phi;
|
|
dcostheta = 1.0 / N_theta;
|
|
factor = 2;
|
|
}
|
|
else if (Symmetry == 0)
|
|
{
|
|
dphi = 2.0 * PI / N_phi;
|
|
dcostheta = 2.0 / N_theta;
|
|
factor = 1;
|
|
}
|
|
else if (myrank == 0)
|
|
{
|
|
cout << "surface_integral::surface_integral: not supported Symmetry setting!" << endl;
|
|
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
}
|
|
|
|
#ifndef GaussInt
|
|
// weight function cover all of [0,pi]
|
|
arcostheta = new double[N_theta];
|
|
#endif
|
|
n_tot = N_theta * N_phi;
|
|
nx_g = new double[n_tot];
|
|
ny_g = new double[n_tot];
|
|
nz_g = new double[n_tot];
|
|
|
|
int n = 0;
|
|
double costheta, sintheta, ph;
|
|
|
|
for (int i = 0; i < N_theta; ++i)
|
|
{
|
|
#ifndef GaussInt
|
|
arcostheta[i] = 1.0 - (i + 0.5) * dcostheta;
|
|
#endif
|
|
costheta = arcostheta[i];
|
|
sintheta = sqrt(1.0 - costheta * costheta);
|
|
|
|
for (int j = 0; j < N_phi; ++j)
|
|
{
|
|
ph = (j + 0.5) * dphi;
|
|
// normal vector respect to the constant R sphere
|
|
nx_g[n] = sintheta * cos(ph);
|
|
ny_g[n] = sintheta * sin(ph);
|
|
nz_g[n] = costheta;
|
|
n++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//|============================================================================
|
|
//| Destructor
|
|
//|============================================================================
|
|
surface_integral::~surface_integral()
|
|
{
|
|
delete[] nx_g;
|
|
delete[] ny_g;
|
|
delete[] nz_g;
|
|
delete[] arcostheta;
|
|
#ifdef GaussInt
|
|
delete[] wtcostheta;
|
|
#endif
|
|
}
|
|
//|----------------------------------------------------------------
|
|
// spin weighted spinw component of psi4, general routine
|
|
// l takes from spinw to maxl; m takes from -l to l
|
|
//|----------------------------------------------------------------
|
|
void surface_integral::surf_Wave(double rex, int lev, cgh *GH, var *Rpsi4, var *Ipsi4,
|
|
int spinw, int maxl, int NN, double *RP, double *IP,
|
|
monitor *Monitor) // NN is the length of RP and IP
|
|
{
|
|
if (myrank == 0 && GH->grids[lev] != 1)
|
|
if (Monitor->outfile)
|
|
Monitor->outfile << "WARNING: surface integral on multipatches" << endl;
|
|
else
|
|
cout << "WARNING: surface integral on multipatches" << endl;
|
|
|
|
const int InList = 2;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Rpsi4);
|
|
DG_List->insert(Ipsi4);
|
|
|
|
int n;
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
int mp, Lp, Nmin, Nmax;
|
|
mp = n_tot / cpusize;
|
|
Lp = n_tot - cpusize * mp;
|
|
if (Lp > myrank)
|
|
{
|
|
Nmin = myrank * mp + myrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = myrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
GH->PatL[lev]->data->Interp_Points(DG_List, n_tot, pox, shellf, Symmetry, Nmin, Nmax);
|
|
|
|
//|~~~~~> Integrate the dot product of Dphi with the surface normal.
|
|
|
|
double *RP_out, *IP_out;
|
|
RP_out = new double[NN];
|
|
IP_out = new double[NN];
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
RP_out[ii] = 0;
|
|
IP_out[ii] = 0;
|
|
}
|
|
// theta part
|
|
double costheta, thetap;
|
|
double cosmphi, sinmphi;
|
|
|
|
int i, j;
|
|
int lpsy = 0;
|
|
if (Symmetry == 0)
|
|
lpsy = 1;
|
|
else if (Symmetry == 1)
|
|
lpsy = 2;
|
|
else if (Symmetry == 2)
|
|
lpsy = 8;
|
|
|
|
double psi4RR, psi4II;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
int countlm = 0;
|
|
for (int pl = spinw; pl < maxl + 1; pl++)
|
|
for (int pm = -pl; pm < pl + 1; pm++)
|
|
{
|
|
for (int lp = 0; lp < lpsy; lp++)
|
|
{
|
|
switch (lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = Rpsi4->SoA[2] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * shellf[InList * n + 1];
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = Rpsi4->SoA[1] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[1] * shellf[InList * n + 1];
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = Rpsi4->SoA[2] * Rpsi4->SoA[1] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * Ipsi4->SoA[1] * shellf[InList * n + 1];
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[2] * Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[1] * Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[1] * Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[2] * Rpsi4->SoA[1] * Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * Ipsi4->SoA[1] * Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
}
|
|
|
|
thetap = sqrt((2 * pl + 1.0) / 4.0 / PI) * misc::Wigner_d_function(pl, pm, spinw, costheta); // note the variation from -2 to 2
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap * (psi4RR * cosmphi + psi4II * sinmphi) * wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap * (psi4II * cosmphi - psi4RR * sinmphi) * wtcostheta[i];
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap * (psi4RR * cosmphi + psi4II * sinmphi);
|
|
IP_out[countlm] = IP_out[countlm] + thetap * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
}
|
|
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
#ifdef GaussInt
|
|
RP_out[ii] = RP_out[ii] * rex * dphi;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi;
|
|
#else
|
|
RP_out[ii] = RP_out[ii] * rex * dphi * dcostheta;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi * dcostheta;
|
|
#endif
|
|
}
|
|
//|------+ Communicate and sum the results from each processor.
|
|
|
|
{
|
|
double *RPIP_out = new double[2 * NN];
|
|
double *RPIP = new double[2 * NN];
|
|
memcpy(RPIP_out, RP_out, NN * sizeof(double));
|
|
memcpy(RPIP_out + NN, IP_out, NN * sizeof(double));
|
|
MPI_Allreduce(RPIP_out, RPIP, 2 * NN, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
|
memcpy(RP, RPIP, NN * sizeof(double));
|
|
memcpy(IP, RPIP + NN, NN * sizeof(double));
|
|
delete[] RPIP_out;
|
|
delete[] RPIP;
|
|
}
|
|
|
|
//|------= Free memory.
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
delete[] RP_out;
|
|
delete[] IP_out;
|
|
DG_List->clearList();
|
|
}
|
|
void surface_integral::surf_Wave(double rex, int lev, cgh *GH, var *Rpsi4, var *Ipsi4,
|
|
int spinw, int maxl, int NN, double *RP, double *IP,
|
|
monitor *Monitor, MPI_Comm Comm_here) // NN is the length of RP and IP
|
|
{
|
|
// misc::tillherecheck(GH->Commlev[lev],GH->start_rank[lev],"start surface_integral::surf_Wave");
|
|
|
|
int lmyrank;
|
|
MPI_Comm_rank(Comm_here, &lmyrank);
|
|
if (lmyrank == 0 && GH->grids[lev] != 1)
|
|
if (Monitor->outfile)
|
|
Monitor->outfile << "WARNING: surface integral on multipatches" << endl;
|
|
else
|
|
cout << "WARNING: surface integral on multipatches" << endl;
|
|
|
|
const int InList = 2;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Rpsi4);
|
|
DG_List->insert(Ipsi4);
|
|
|
|
int n;
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
// misc::tillherecheck(GH->Commlev[lev],GH->start_rank[lev],"before Interp_Points");
|
|
|
|
GH->PatL[lev]->data->Interp_Points(DG_List, n_tot, pox, shellf, Symmetry, Comm_here);
|
|
|
|
// misc::tillherecheck(GH->Commlev[lev],GH->start_rank[lev],"after Interp_Points");
|
|
|
|
int mp, Lp, Nmin, Nmax;
|
|
|
|
int cpusize_here;
|
|
MPI_Comm_size(Comm_here, &cpusize_here);
|
|
|
|
mp = n_tot / cpusize_here;
|
|
Lp = n_tot - cpusize_here * mp;
|
|
|
|
if (Lp > lmyrank)
|
|
{
|
|
Nmin = lmyrank * mp + lmyrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = lmyrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
//|~~~~~> Integrate the dot product of Dphi with the surface normal.
|
|
|
|
double *RP_out, *IP_out;
|
|
RP_out = new double[NN];
|
|
IP_out = new double[NN];
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
RP_out[ii] = 0;
|
|
IP_out[ii] = 0;
|
|
}
|
|
// theta part
|
|
double costheta, thetap;
|
|
double cosmphi, sinmphi;
|
|
|
|
int i, j;
|
|
int lpsy = 0;
|
|
if (Symmetry == 0)
|
|
lpsy = 1;
|
|
else if (Symmetry == 1)
|
|
lpsy = 2;
|
|
else if (Symmetry == 2)
|
|
lpsy = 8;
|
|
|
|
double psi4RR, psi4II;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
int countlm = 0;
|
|
for (int pl = spinw; pl < maxl + 1; pl++)
|
|
for (int pm = -pl; pm < pl + 1; pm++)
|
|
{
|
|
for (int lp = 0; lp < lpsy; lp++)
|
|
{
|
|
switch (lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = Rpsi4->SoA[2] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * shellf[InList * n + 1];
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = Rpsi4->SoA[1] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[1] * shellf[InList * n + 1];
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = Rpsi4->SoA[2] * Rpsi4->SoA[1] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * Ipsi4->SoA[1] * shellf[InList * n + 1];
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[2] * Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[1] * Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[1] * Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[2] * Rpsi4->SoA[1] * Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * Ipsi4->SoA[1] * Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
}
|
|
|
|
thetap = sqrt((2 * pl + 1.0) / 4.0 / PI) * misc::Wigner_d_function(pl, pm, spinw, costheta); // note the variation from -2 to 2
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap * (psi4RR * cosmphi + psi4II * sinmphi) * wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap * (psi4II * cosmphi - psi4RR * sinmphi) * wtcostheta[i];
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap * (psi4RR * cosmphi + psi4II * sinmphi);
|
|
IP_out[countlm] = IP_out[countlm] + thetap * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
}
|
|
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
#ifdef GaussInt
|
|
RP_out[ii] = RP_out[ii] * rex * dphi;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi;
|
|
#else
|
|
RP_out[ii] = RP_out[ii] * rex * dphi * dcostheta;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi * dcostheta;
|
|
#endif
|
|
}
|
|
//|------+ Communicate and sum the results from each processor.
|
|
|
|
{
|
|
double *RPIP_out = new double[2 * NN];
|
|
double *RPIP = new double[2 * NN];
|
|
memcpy(RPIP_out, RP_out, NN * sizeof(double));
|
|
memcpy(RPIP_out + NN, IP_out, NN * sizeof(double));
|
|
MPI_Allreduce(RPIP_out, RPIP, 2 * NN, MPI_DOUBLE, MPI_SUM, Comm_here);
|
|
memcpy(RP, RPIP, NN * sizeof(double));
|
|
memcpy(IP, RPIP + NN, NN * sizeof(double));
|
|
delete[] RPIP_out;
|
|
delete[] RPIP;
|
|
}
|
|
|
|
//|------= Free memory.
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
delete[] RP_out;
|
|
delete[] IP_out;
|
|
DG_List->clearList();
|
|
}
|
|
//|----------------------------------------------------------------
|
|
// for shell patch
|
|
//|----------------------------------------------------------------
|
|
void surface_integral::surf_Wave(double rex, int lev, ShellPatch *GH, var *Rpsi4, var *Ipsi4,
|
|
int spinw, int maxl, int NN, double *RP, double *IP,
|
|
monitor *Monitor) // NN is the length of RP and IP
|
|
{
|
|
const int InList = 2;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Rpsi4);
|
|
DG_List->insert(Ipsi4);
|
|
|
|
int n;
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
GH->Interp_Points(DG_List, n_tot, pox, shellf, Symmetry);
|
|
|
|
int mp, Lp, Nmin, Nmax;
|
|
|
|
mp = n_tot / cpusize;
|
|
Lp = n_tot - cpusize * mp;
|
|
|
|
if (Lp > myrank)
|
|
{
|
|
Nmin = myrank * mp + myrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = myrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
//|~~~~~> Integrate the dot product of Dphi with the surface normal.
|
|
|
|
double *RP_out, *IP_out;
|
|
RP_out = new double[NN];
|
|
IP_out = new double[NN];
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
RP_out[ii] = 0;
|
|
IP_out[ii] = 0;
|
|
}
|
|
// theta part
|
|
double costheta, thetap;
|
|
double cosmphi, sinmphi;
|
|
|
|
int i, j;
|
|
int lpsy = 0;
|
|
if (Symmetry == 0)
|
|
lpsy = 1;
|
|
else if (Symmetry == 1)
|
|
lpsy = 2;
|
|
else if (Symmetry == 2)
|
|
lpsy = 8;
|
|
|
|
double psi4RR, psi4II;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
int countlm = 0;
|
|
for (int pl = spinw; pl < maxl + 1; pl++)
|
|
for (int pm = -pl; pm < pl + 1; pm++)
|
|
{
|
|
for (int lp = 0; lp < lpsy; lp++)
|
|
{
|
|
switch (lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = Rpsi4->SoA[2] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * shellf[InList * n + 1];
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = Rpsi4->SoA[1] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[1] * shellf[InList * n + 1];
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = Rpsi4->SoA[2] * Rpsi4->SoA[1] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * Ipsi4->SoA[1] * shellf[InList * n + 1];
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[2] * Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[1] * Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[1] * Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
psi4RR = Rpsi4->SoA[2] * Rpsi4->SoA[1] * Rpsi4->SoA[0] * shellf[InList * n];
|
|
psi4II = Ipsi4->SoA[2] * Ipsi4->SoA[1] * Ipsi4->SoA[0] * shellf[InList * n + 1];
|
|
}
|
|
|
|
thetap = sqrt((2 * pl + 1.0) / 4.0 / PI) * misc::Wigner_d_function(pl, pm, spinw, costheta); // note the variation from -2 to 2
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap * (psi4RR * cosmphi + psi4II * sinmphi) * wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap * (psi4II * cosmphi - psi4RR * sinmphi) * wtcostheta[i];
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap * (psi4RR * cosmphi + psi4II * sinmphi);
|
|
IP_out[countlm] = IP_out[countlm] + thetap * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
}
|
|
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
#ifdef GaussInt
|
|
RP_out[ii] = RP_out[ii] * rex * dphi;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi;
|
|
#else
|
|
RP_out[ii] = RP_out[ii] * rex * dphi * dcostheta;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi * dcostheta;
|
|
#endif
|
|
}
|
|
//|------+ Communicate and sum the results from each processor.
|
|
|
|
{
|
|
double *RPIP_out = new double[2 * NN];
|
|
double *RPIP = new double[2 * NN];
|
|
memcpy(RPIP_out, RP_out, NN * sizeof(double));
|
|
memcpy(RPIP_out + NN, IP_out, NN * sizeof(double));
|
|
MPI_Allreduce(RPIP_out, RPIP, 2 * NN, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
|
memcpy(RP, RPIP, NN * sizeof(double));
|
|
memcpy(IP, RPIP + NN, NN * sizeof(double));
|
|
delete[] RPIP_out;
|
|
delete[] RPIP;
|
|
}
|
|
|
|
//|------= Free memory.
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
delete[] RP_out;
|
|
delete[] IP_out;
|
|
DG_List->clearList();
|
|
}
|
|
//|----------------------------------------------------------------
|
|
// for shell patch
|
|
// for EM wave specially symmetric case
|
|
//|----------------------------------------------------------------
|
|
void surface_integral::surf_Wave(double rex, int lev, ShellPatch *GH,
|
|
var *Ex, var *Ey, var *Ez, var *Bx, var *By, var *Bz,
|
|
var *chi, var *gxx, var *gxy, var *gxz, var *gyy, var *gyz, var *gzz,
|
|
int spinw, int maxl, int NN, double *RP, double *IP,
|
|
monitor *Monitor) // NN is the length of RP and IP
|
|
{
|
|
const int InList = 13;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Ex);
|
|
DG_List->insert(Ey);
|
|
DG_List->insert(Ez);
|
|
DG_List->insert(Bx);
|
|
DG_List->insert(By);
|
|
DG_List->insert(Bz);
|
|
DG_List->insert(chi);
|
|
DG_List->insert(gxx);
|
|
DG_List->insert(gxy);
|
|
DG_List->insert(gxz);
|
|
DG_List->insert(gyy);
|
|
DG_List->insert(gyz);
|
|
DG_List->insert(gzz);
|
|
|
|
int n;
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
GH->Interp_Points(DG_List, n_tot, pox, shellf, Symmetry);
|
|
|
|
int mp, Lp, Nmin, Nmax;
|
|
|
|
mp = n_tot / cpusize;
|
|
Lp = n_tot - cpusize * mp;
|
|
|
|
if (Lp > myrank)
|
|
{
|
|
Nmin = myrank * mp + myrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = myrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
//|~~~~~> Integrate the dot product of Dphi with the surface normal.
|
|
|
|
double *RP_out, *IP_out;
|
|
RP_out = new double[NN];
|
|
IP_out = new double[NN];
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
RP_out[ii] = 0;
|
|
IP_out[ii] = 0;
|
|
}
|
|
// theta part
|
|
double costheta, thetap;
|
|
double cosmphi, sinmphi;
|
|
|
|
int i, j;
|
|
int lpsy = 0;
|
|
if (Symmetry == 0)
|
|
lpsy = 1;
|
|
else if (Symmetry == 1)
|
|
lpsy = 2;
|
|
else if (Symmetry == 2)
|
|
lpsy = 8;
|
|
|
|
double psi4RR, psi4II;
|
|
double px, py, pz;
|
|
double pEx, pEy, pEz, pBx, pBy, pBz;
|
|
double pchi, pgxx, pgxy, pgxz, pgyy, pgyz, pgzz;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
int countlm = 0;
|
|
for (int pl = spinw; pl < maxl + 1; pl++)
|
|
for (int pm = -pl; pm < pl + 1; pm++)
|
|
{
|
|
for (int lp = 0; lp < lpsy; lp++)
|
|
{
|
|
px = pox[0][n];
|
|
py = pox[1][n];
|
|
pz = pox[2][n];
|
|
pEx = shellf[InList * n];
|
|
pEy = shellf[InList * n + 1];
|
|
pEz = shellf[InList * n + 2];
|
|
pBx = shellf[InList * n + 3];
|
|
pBy = shellf[InList * n + 4];
|
|
pBz = shellf[InList * n + 5];
|
|
pchi = shellf[InList * n + 6];
|
|
pgxx = shellf[InList * n + 7];
|
|
pgxy = shellf[InList * n + 8];
|
|
pgxz = shellf[InList * n + 9];
|
|
pgyy = shellf[InList * n + 10];
|
|
pgyz = shellf[InList * n + 11];
|
|
pgzz = shellf[InList * n + 12];
|
|
switch (lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
pz = -pz;
|
|
pEz = -pEz;
|
|
pBx = -pBx;
|
|
pBy = -pBy;
|
|
pgxz = -pgxz;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
py = -py;
|
|
pEy = -pEy;
|
|
pBx = -pBx;
|
|
pBz = -pBz;
|
|
pgxy = -pgxy;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
py = -py;
|
|
pz = -pz;
|
|
pEz = -pEz;
|
|
pBz = -pBz;
|
|
pgxz = -pgxz;
|
|
pEy = -pEy;
|
|
pBy = -pBy;
|
|
pgxy = -pgxy;
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
px = -px;
|
|
pEx = -pEx;
|
|
pBy = -pBy;
|
|
pBz = -pBz;
|
|
pgxy = -pgxy;
|
|
pgxz = -pgxz;
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
pz = -pz;
|
|
px = -px;
|
|
pEz = -pEz;
|
|
pBz = -pBz;
|
|
pgyz = -pgyz;
|
|
pEx = -pEx;
|
|
pBx = -pBx;
|
|
pgxy = -pgxy;
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
px = -px;
|
|
py = -py;
|
|
pEx = -pEx;
|
|
pBx = -pBx;
|
|
pgxz = -pgxz;
|
|
pEy = -pEy;
|
|
pBy = -pBy;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
px = -px;
|
|
py = -py;
|
|
pz = -pz;
|
|
pEx = -pEx;
|
|
pEy = -pEy;
|
|
pEz = -pEz;
|
|
}
|
|
|
|
f_getnpem2_point(px, py, pz, pchi, pgxx, pgxy, pgxz, pgyy, pgyz, pgzz, pEx, pEy, pEz, pBx, pBy, pBz,
|
|
psi4RR, psi4II);
|
|
thetap = sqrt((2 * pl + 1.0) / 4.0 / PI) * misc::Wigner_d_function(pl, pm, spinw, costheta); // note the variation from -2 to 2
|
|
|
|
// find back the one
|
|
pchi = pchi + 1;
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap / pchi / pchi * (psi4RR * cosmphi + psi4II * sinmphi) * wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap / pchi / pchi * (psi4II * cosmphi - psi4RR * sinmphi) * wtcostheta[i];
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap / pchi / pchi * (psi4RR * cosmphi + psi4II * sinmphi);
|
|
IP_out[countlm] = IP_out[countlm] + thetap / pchi / pchi * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
}
|
|
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
#ifdef GaussInt
|
|
RP_out[ii] = RP_out[ii] * rex * dphi;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi;
|
|
#else
|
|
RP_out[ii] = RP_out[ii] * rex * dphi * dcostheta;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi * dcostheta;
|
|
#endif
|
|
}
|
|
//|------+ Communicate and sum the results from each processor.
|
|
|
|
{
|
|
double *RPIP_out = new double[2 * NN];
|
|
double *RPIP = new double[2 * NN];
|
|
memcpy(RPIP_out, RP_out, NN * sizeof(double));
|
|
memcpy(RPIP_out + NN, IP_out, NN * sizeof(double));
|
|
MPI_Allreduce(RPIP_out, RPIP, 2 * NN, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
|
memcpy(RP, RPIP, NN * sizeof(double));
|
|
memcpy(IP, RPIP + NN, NN * sizeof(double));
|
|
delete[] RPIP_out;
|
|
delete[] RPIP;
|
|
}
|
|
|
|
//|------= Free memory.
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
delete[] RP_out;
|
|
delete[] IP_out;
|
|
DG_List->clearList();
|
|
}
|
|
//|----------------------------------------------------------------
|
|
// for shell patch
|
|
// for EM wave specially symmetric case
|
|
// unify for phi1 and phi2
|
|
//|----------------------------------------------------------------
|
|
void surface_integral::surf_Wave(double rex, int lev, ShellPatch *GH,
|
|
var *Ex, var *Ey, var *Ez, var *Bx, var *By, var *Bz,
|
|
var *chi, var *gxx, var *gxy, var *gxz, var *gyy, var *gyz, var *gzz,
|
|
int spinw, int maxl, int NN, double *RP, double *IP,
|
|
monitor *Monitor,
|
|
void (*funcs)(double &, double &, double &,
|
|
double &, double &, double &, double &, double &, double &, double &,
|
|
double &, double &, double &, double &, double &, double &,
|
|
double &, double &)) // NN is the length of RP and IP
|
|
{
|
|
const int InList = 13;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Ex);
|
|
DG_List->insert(Ey);
|
|
DG_List->insert(Ez);
|
|
DG_List->insert(Bx);
|
|
DG_List->insert(By);
|
|
DG_List->insert(Bz);
|
|
DG_List->insert(chi);
|
|
DG_List->insert(gxx);
|
|
DG_List->insert(gxy);
|
|
DG_List->insert(gxz);
|
|
DG_List->insert(gyy);
|
|
DG_List->insert(gyz);
|
|
DG_List->insert(gzz);
|
|
|
|
int n;
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
GH->Interp_Points(DG_List, n_tot, pox, shellf, Symmetry);
|
|
|
|
double *RP_out, *IP_out;
|
|
RP_out = new double[NN];
|
|
IP_out = new double[NN];
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
RP_out[ii] = 0;
|
|
IP_out[ii] = 0;
|
|
}
|
|
|
|
#if 0
|
|
// for debug
|
|
if(myrank==0)
|
|
{
|
|
double costheta, thetap;
|
|
double cosmphi,sinmphi;
|
|
|
|
int i,j;
|
|
int lpsy=0;
|
|
if( Symmetry == 0 ) lpsy=1;
|
|
else if( Symmetry == 1 ) lpsy=2;
|
|
else if( Symmetry == 2 ) lpsy=8;
|
|
|
|
double psi4RR,psi4II;
|
|
double px,py,pz;
|
|
double pEx,pEy,pEz,pBx,pBy,pBz;
|
|
double pchi,pgxx,pgxy,pgxz,pgyy,pgyz,pgzz;
|
|
for( n = 0; n <= n_tot-1; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n/N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
for(int lp=0;lp<lpsy;lp++)
|
|
{
|
|
px = pox[0][n];
|
|
py = pox[1][n];
|
|
pz = pox[2][n];
|
|
pEx = shellf[InList*n ];
|
|
pEy = shellf[InList*n+1];
|
|
pEz = shellf[InList*n+2];
|
|
pBx = shellf[InList*n+3];
|
|
pBy = shellf[InList*n+4];
|
|
pBz = shellf[InList*n+5];
|
|
pchi = shellf[InList*n+6];
|
|
pgxx = shellf[InList*n+7];
|
|
pgxy = shellf[InList*n+8];
|
|
pgxz = shellf[InList*n+9];
|
|
pgyy = shellf[InList*n+10];
|
|
pgyz = shellf[InList*n+11];
|
|
pgzz = shellf[InList*n+12];
|
|
switch(lp)
|
|
{
|
|
case 1: //++- (pi-theta, phi)
|
|
pz = -pz;
|
|
pEz = -pEz;
|
|
pBx = -pBx;
|
|
pBy = -pBy;
|
|
pgxz = -pgxz;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
py = -py;
|
|
pEy = -pEy;
|
|
pBx = -pBx;
|
|
pBz = -pBz;
|
|
pgxy = -pgxy;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
py = -py;
|
|
pz = -pz;
|
|
pEz = -pEz;
|
|
pBz = -pBz;;
|
|
pgxz = -pgxz;
|
|
pEy = -pEy;
|
|
pBy = -pBy;
|
|
pgxy = -pgxy;
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
px = -px;
|
|
pEx = -pEx;
|
|
pBy = -pBy;
|
|
pBz = -pBz;
|
|
pgxy = -pgxy;
|
|
pgxz = -pgxz;
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
pz = -pz;
|
|
px = -px;
|
|
pEz = -pEz;
|
|
pBz = -pBz;
|
|
pgyz = -pgyz;
|
|
pEx = -pEx;
|
|
pBx = -pBx;
|
|
pgxy = -pgxy;
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
px = -px;
|
|
py = -py;
|
|
pEx = -pEx;
|
|
pBx = -pBx;
|
|
pgxz = -pgxz;
|
|
pEy = -pEy;
|
|
pBy = -pBy;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
px = -px;
|
|
py = -py;
|
|
pz = -pz;
|
|
pEx = -pEx;
|
|
pEy = -pEy;
|
|
pEz = -pEz;
|
|
}
|
|
|
|
funcs(px,py,pz,pchi,pgxx,pgxy,pgxz,pgyy,pgyz,pgzz,pEx,pEy,pEz,pBx,pBy,pBz,
|
|
psi4RR,psi4II);
|
|
// if(n==0 || n==N_phi/2-1 || n==N_phi/2 || n==N_phi-1 ||
|
|
// n==N_phi*(N_theta-1)+0 || n==N_phi*(N_theta-1)+N_phi/2-1 || n==N_phi*(N_theta-1)+N_phi/2 || n==N_phi*(N_theta-1)+N_phi-1)
|
|
// cout<<px<<","<<py<<","<<pz<<","<<pchi<<","<<pgxx<<","<<pgxy<<","<<pgxz<<","<<pgyy<<","<<pgyz<<","<<pgzz<<","<<pEx<<","
|
|
// <<pEy<<","<<pEz<<","<<pBx<<","<<pBy<<","<<pBz<<","<<psi4RR<<","<<psi4II<<endl<<endl;
|
|
|
|
// find back the one
|
|
pchi = pchi+1;
|
|
|
|
int countlm=0;
|
|
for(int pl=spinw;pl<maxl+1;pl++)
|
|
for(int pm=-pl;pm<pl+1;pm++)
|
|
{
|
|
switch(lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j+0.5) * dphi);
|
|
sinmphi = sin(pm * (j+0.5) * dphi);
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j+0.5) * dphi);
|
|
sinmphi = sin(pm * (j+0.5) * dphi);
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j+0.5) * dphi);
|
|
sinmphi =-sin(pm * (j+0.5) * dphi);
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j+0.5) * dphi);
|
|
sinmphi =-sin(pm * (j+0.5) * dphi);
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j+0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j+0.5) * dphi));
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j+0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j+0.5) * dphi));
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j+0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j+0.5) * dphi));
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j+0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j+0.5) * dphi));
|
|
}
|
|
thetap = sqrt((2*pl+1.0)/4.0/PI)*misc::Wigner_d_function(pl,pm,spinw,costheta); //note the variation from -2 to 2
|
|
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap/pchi/pchi * (psi4RR * cosmphi + psi4II * sinmphi)*wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap/pchi/pchi * (psi4II * cosmphi - psi4RR * sinmphi)*wtcostheta[i];
|
|
if(pl==2 && pm==0) cout<<countlm+1<<","<<RP_out[countlm] * rex * dphi<<endl;
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap/pchi/pchi * (psi4RR * cosmphi + psi4II * sinmphi);
|
|
IP_out[countlm] = IP_out[countlm] + thetap/pchi/pchi * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
countlm++; //no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
// if(Symmetry == 2) MPI_Abort(MPI_COMM_WORLD,1);
|
|
}
|
|
MPI_Abort(MPI_COMM_WORLD,1);
|
|
}
|
|
#else
|
|
int mp, Lp, Nmin, Nmax;
|
|
|
|
mp = n_tot / cpusize;
|
|
Lp = n_tot - cpusize * mp;
|
|
|
|
if (Lp > myrank)
|
|
{
|
|
Nmin = myrank * mp + myrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = myrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
// theta part
|
|
double costheta, thetap;
|
|
double cosmphi, sinmphi;
|
|
|
|
int i, j;
|
|
int lpsy = 0;
|
|
if (Symmetry == 0)
|
|
lpsy = 1;
|
|
else if (Symmetry == 1)
|
|
lpsy = 2;
|
|
else if (Symmetry == 2)
|
|
lpsy = 8;
|
|
|
|
double psi4RR, psi4II;
|
|
double px, py, pz;
|
|
double pEx, pEy, pEz, pBx, pBy, pBz;
|
|
double pchi, pgxx, pgxy, pgxz, pgyy, pgyz, pgzz;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
int countlm = 0;
|
|
for (int pl = spinw; pl < maxl + 1; pl++)
|
|
for (int pm = -pl; pm < pl + 1; pm++)
|
|
{
|
|
for (int lp = 0; lp < lpsy; lp++)
|
|
{
|
|
px = pox[0][n];
|
|
py = pox[1][n];
|
|
pz = pox[2][n];
|
|
pEx = shellf[InList * n];
|
|
pEy = shellf[InList * n + 1];
|
|
pEz = shellf[InList * n + 2];
|
|
pBx = shellf[InList * n + 3];
|
|
pBy = shellf[InList * n + 4];
|
|
pBz = shellf[InList * n + 5];
|
|
pchi = shellf[InList * n + 6];
|
|
pgxx = shellf[InList * n + 7];
|
|
pgxy = shellf[InList * n + 8];
|
|
pgxz = shellf[InList * n + 9];
|
|
pgyy = shellf[InList * n + 10];
|
|
pgyz = shellf[InList * n + 11];
|
|
pgzz = shellf[InList * n + 12];
|
|
switch (lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
pz = -pz;
|
|
pEz = -pEz;
|
|
pBx = -pBx;
|
|
pBy = -pBy;
|
|
pgxz = -pgxz;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
py = -py;
|
|
pEy = -pEy;
|
|
pBx = -pBx;
|
|
pBz = -pBz;
|
|
pgxy = -pgxy;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
py = -py;
|
|
pz = -pz;
|
|
pEz = -pEz;
|
|
pBz = -pBz;
|
|
pgxz = -pgxz;
|
|
pEy = -pEy;
|
|
pBy = -pBy;
|
|
pgxy = -pgxy;
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
px = -px;
|
|
pEx = -pEx;
|
|
pBy = -pBy;
|
|
pBz = -pBz;
|
|
pgxy = -pgxy;
|
|
pgxz = -pgxz;
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
pz = -pz;
|
|
px = -px;
|
|
pEz = -pEz;
|
|
pBz = -pBz;
|
|
pgyz = -pgyz;
|
|
pEx = -pEx;
|
|
pBx = -pBx;
|
|
pgxy = -pgxy;
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
px = -px;
|
|
py = -py;
|
|
pEx = -pEx;
|
|
pBx = -pBx;
|
|
pgxz = -pgxz;
|
|
pEy = -pEy;
|
|
pBy = -pBy;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
px = -px;
|
|
py = -py;
|
|
pz = -pz;
|
|
pEx = -pEx;
|
|
pEy = -pEy;
|
|
pEz = -pEz;
|
|
}
|
|
|
|
funcs(px, py, pz, pchi, pgxx, pgxy, pgxz, pgyy, pgyz, pgzz, pEx, pEy, pEz, pBx, pBy, pBz,
|
|
psi4RR, psi4II);
|
|
thetap = sqrt((2 * pl + 1.0) / 4.0 / PI) * misc::Wigner_d_function(pl, pm, spinw, costheta); // note the variation from -2 to 2
|
|
|
|
// find back the one
|
|
pchi = pchi + 1;
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap / pchi / pchi * (psi4RR * cosmphi + psi4II * sinmphi) * wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap / pchi / pchi * (psi4II * cosmphi - psi4RR * sinmphi) * wtcostheta[i];
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap / pchi / pchi * (psi4RR * cosmphi + psi4II * sinmphi);
|
|
IP_out[countlm] = IP_out[countlm] + thetap / pchi / pchi * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
}
|
|
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
#endif
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
#ifdef GaussInt
|
|
RP_out[ii] = RP_out[ii] * rex * dphi;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi;
|
|
#else
|
|
RP_out[ii] = RP_out[ii] * rex * dphi * dcostheta;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi * dcostheta;
|
|
#endif
|
|
}
|
|
//|------+ Communicate and sum the results from each processor.
|
|
|
|
{
|
|
double *RPIP_out = new double[2 * NN];
|
|
double *RPIP = new double[2 * NN];
|
|
memcpy(RPIP_out, RP_out, NN * sizeof(double));
|
|
memcpy(RPIP_out + NN, IP_out, NN * sizeof(double));
|
|
MPI_Allreduce(RPIP_out, RPIP, 2 * NN, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
|
memcpy(RP, RPIP, NN * sizeof(double));
|
|
memcpy(IP, RPIP + NN, NN * sizeof(double));
|
|
delete[] RPIP_out;
|
|
delete[] RPIP;
|
|
}
|
|
|
|
//|------= Free memory.
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
delete[] RP_out;
|
|
delete[] IP_out;
|
|
DG_List->clearList();
|
|
}
|
|
//|----------------------------------------------------------------
|
|
// for box
|
|
// for EM wave specially symmetric case
|
|
// unify for phi1 and phi2
|
|
//|----------------------------------------------------------------
|
|
void surface_integral::surf_Wave(double rex, int lev, cgh *GH,
|
|
var *Ex, var *Ey, var *Ez, var *Bx, var *By, var *Bz,
|
|
var *chi, var *gxx, var *gxy, var *gxz, var *gyy, var *gyz, var *gzz,
|
|
int spinw, int maxl, int NN, double *RP, double *IP,
|
|
monitor *Monitor,
|
|
void (*funcs)(double &, double &, double &,
|
|
double &, double &, double &, double &, double &, double &, double &,
|
|
double &, double &, double &, double &, double &, double &,
|
|
double &, double &)) // NN is the length of RP and IP
|
|
{
|
|
const int InList = 13;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Ex);
|
|
DG_List->insert(Ey);
|
|
DG_List->insert(Ez);
|
|
DG_List->insert(Bx);
|
|
DG_List->insert(By);
|
|
DG_List->insert(Bz);
|
|
DG_List->insert(chi);
|
|
DG_List->insert(gxx);
|
|
DG_List->insert(gxy);
|
|
DG_List->insert(gxz);
|
|
DG_List->insert(gyy);
|
|
DG_List->insert(gyz);
|
|
DG_List->insert(gzz);
|
|
|
|
int n;
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
GH->PatL[lev]->data->Interp_Points(DG_List, n_tot, pox, shellf, Symmetry);
|
|
|
|
double *RP_out, *IP_out;
|
|
RP_out = new double[NN];
|
|
IP_out = new double[NN];
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
RP_out[ii] = 0;
|
|
IP_out[ii] = 0;
|
|
}
|
|
|
|
#if 0
|
|
// for debug
|
|
if(myrank==0)
|
|
{
|
|
double costheta, thetap;
|
|
double cosmphi,sinmphi;
|
|
|
|
int i,j;
|
|
int lpsy=0;
|
|
if( Symmetry == 0 ) lpsy=1;
|
|
else if( Symmetry == 1 ) lpsy=2;
|
|
else if( Symmetry == 2 ) lpsy=8;
|
|
|
|
double psi4RR,psi4II;
|
|
double px,py,pz;
|
|
double pEx,pEy,pEz,pBx,pBy,pBz;
|
|
double pchi,pgxx,pgxy,pgxz,pgyy,pgyz,pgzz;
|
|
for( n = 0; n <= n_tot-1; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n/N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
for(int lp=0;lp<lpsy;lp++)
|
|
{
|
|
px = pox[0][n];
|
|
py = pox[1][n];
|
|
pz = pox[2][n];
|
|
pEx = shellf[InList*n ];
|
|
pEy = shellf[InList*n+1];
|
|
pEz = shellf[InList*n+2];
|
|
pBx = shellf[InList*n+3];
|
|
pBy = shellf[InList*n+4];
|
|
pBz = shellf[InList*n+5];
|
|
pchi = shellf[InList*n+6];
|
|
pgxx = shellf[InList*n+7];
|
|
pgxy = shellf[InList*n+8];
|
|
pgxz = shellf[InList*n+9];
|
|
pgyy = shellf[InList*n+10];
|
|
pgyz = shellf[InList*n+11];
|
|
pgzz = shellf[InList*n+12];
|
|
switch(lp)
|
|
{
|
|
case 1: //++- (pi-theta, phi)
|
|
pz = -pz;
|
|
pEz = -pEz;
|
|
pBx = -pBx;
|
|
pBy = -pBy;
|
|
pgxz = -pgxz;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
py = -py;
|
|
pEy = -pEy;
|
|
pBx = -pBx;
|
|
pBz = -pBz;
|
|
pgxy = -pgxy;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
py = -py;
|
|
pz = -pz;
|
|
pEz = -pEz;
|
|
pBz = -pBz;;
|
|
pgxz = -pgxz;
|
|
pEy = -pEy;
|
|
pBy = -pBy;
|
|
pgxy = -pgxy;
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
px = -px;
|
|
pEx = -pEx;
|
|
pBy = -pBy;
|
|
pBz = -pBz;
|
|
pgxy = -pgxy;
|
|
pgxz = -pgxz;
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
pz = -pz;
|
|
px = -px;
|
|
pEz = -pEz;
|
|
pBz = -pBz;
|
|
pgyz = -pgyz;
|
|
pEx = -pEx;
|
|
pBx = -pBx;
|
|
pgxy = -pgxy;
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
px = -px;
|
|
py = -py;
|
|
pEx = -pEx;
|
|
pBx = -pBx;
|
|
pgxz = -pgxz;
|
|
pEy = -pEy;
|
|
pBy = -pBy;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
px = -px;
|
|
py = -py;
|
|
pz = -pz;
|
|
pEx = -pEx;
|
|
pEy = -pEy;
|
|
pEz = -pEz;
|
|
}
|
|
|
|
funcs(px,py,pz,pchi,pgxx,pgxy,pgxz,pgyy,pgyz,pgzz,pEx,pEy,pEz,pBx,pBy,pBz,
|
|
psi4RR,psi4II);
|
|
// if(n==0 || n==N_phi/2-1 || n==N_phi/2 || n==N_phi-1 ||
|
|
// n==N_phi*(N_theta-1)+0 || n==N_phi*(N_theta-1)+N_phi/2-1 || n==N_phi*(N_theta-1)+N_phi/2 || n==N_phi*(N_theta-1)+N_phi-1)
|
|
// cout<<px<<","<<py<<","<<pz<<","<<pchi<<","<<pgxx<<","<<pgxy<<","<<pgxz<<","<<pgyy<<","<<pgyz<<","<<pgzz<<","<<pEx<<","
|
|
// <<pEy<<","<<pEz<<","<<pBx<<","<<pBy<<","<<pBz<<","<<psi4RR<<","<<psi4II<<endl<<endl;
|
|
|
|
// find back the one
|
|
pchi = pchi+1;
|
|
|
|
int countlm=0;
|
|
for(int pl=spinw;pl<maxl+1;pl++)
|
|
for(int pm=-pl;pm<pl+1;pm++)
|
|
{
|
|
switch(lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j+0.5) * dphi);
|
|
sinmphi = sin(pm * (j+0.5) * dphi);
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j+0.5) * dphi);
|
|
sinmphi = sin(pm * (j+0.5) * dphi);
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j+0.5) * dphi);
|
|
sinmphi =-sin(pm * (j+0.5) * dphi);
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j+0.5) * dphi);
|
|
sinmphi =-sin(pm * (j+0.5) * dphi);
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j+0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j+0.5) * dphi));
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j+0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j+0.5) * dphi));
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j+0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j+0.5) * dphi));
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j+0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j+0.5) * dphi));
|
|
}
|
|
thetap = sqrt((2*pl+1.0)/4.0/PI)*misc::Wigner_d_function(pl,pm,spinw,costheta); //note the variation from -2 to 2
|
|
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap/pchi/pchi * (psi4RR * cosmphi + psi4II * sinmphi)*wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap/pchi/pchi * (psi4II * cosmphi - psi4RR * sinmphi)*wtcostheta[i];
|
|
if(pl==2 && pm==0) cout<<countlm+1<<","<<RP_out[countlm] * rex * dphi<<endl;
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap/pchi/pchi * (psi4RR * cosmphi + psi4II * sinmphi);
|
|
IP_out[countlm] = IP_out[countlm] + thetap/pchi/pchi * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
countlm++; //no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
// if(Symmetry == 2) MPI_Abort(MPI_COMM_WORLD,1);
|
|
}
|
|
MPI_Abort(MPI_COMM_WORLD,1);
|
|
}
|
|
#else
|
|
int mp, Lp, Nmin, Nmax;
|
|
|
|
mp = n_tot / cpusize;
|
|
Lp = n_tot - cpusize * mp;
|
|
|
|
if (Lp > myrank)
|
|
{
|
|
Nmin = myrank * mp + myrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = myrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
// theta part
|
|
double costheta, thetap;
|
|
double cosmphi, sinmphi;
|
|
|
|
int i, j;
|
|
int lpsy = 0;
|
|
if (Symmetry == 0)
|
|
lpsy = 1;
|
|
else if (Symmetry == 1)
|
|
lpsy = 2;
|
|
else if (Symmetry == 2)
|
|
lpsy = 8;
|
|
|
|
double psi4RR, psi4II;
|
|
double px, py, pz;
|
|
double pEx, pEy, pEz, pBx, pBy, pBz;
|
|
double pchi, pgxx, pgxy, pgxz, pgyy, pgyz, pgzz;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
int countlm = 0;
|
|
for (int pl = spinw; pl < maxl + 1; pl++)
|
|
for (int pm = -pl; pm < pl + 1; pm++)
|
|
{
|
|
for (int lp = 0; lp < lpsy; lp++)
|
|
{
|
|
px = pox[0][n];
|
|
py = pox[1][n];
|
|
pz = pox[2][n];
|
|
pEx = shellf[InList * n];
|
|
pEy = shellf[InList * n + 1];
|
|
pEz = shellf[InList * n + 2];
|
|
pBx = shellf[InList * n + 3];
|
|
pBy = shellf[InList * n + 4];
|
|
pBz = shellf[InList * n + 5];
|
|
pchi = shellf[InList * n + 6];
|
|
pgxx = shellf[InList * n + 7];
|
|
pgxy = shellf[InList * n + 8];
|
|
pgxz = shellf[InList * n + 9];
|
|
pgyy = shellf[InList * n + 10];
|
|
pgyz = shellf[InList * n + 11];
|
|
pgzz = shellf[InList * n + 12];
|
|
switch (lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
pz = -pz;
|
|
pEz = -pEz;
|
|
pBx = -pBx;
|
|
pBy = -pBy;
|
|
pgxz = -pgxz;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
py = -py;
|
|
pEy = -pEy;
|
|
pBx = -pBx;
|
|
pBz = -pBz;
|
|
pgxy = -pgxy;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
py = -py;
|
|
pz = -pz;
|
|
pEz = -pEz;
|
|
pBz = -pBz;
|
|
pgxz = -pgxz;
|
|
pEy = -pEy;
|
|
pBy = -pBy;
|
|
pgxy = -pgxy;
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
px = -px;
|
|
pEx = -pEx;
|
|
pBy = -pBy;
|
|
pBz = -pBz;
|
|
pgxy = -pgxy;
|
|
pgxz = -pgxz;
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
pz = -pz;
|
|
px = -px;
|
|
pEz = -pEz;
|
|
pBz = -pBz;
|
|
pgyz = -pgyz;
|
|
pEx = -pEx;
|
|
pBx = -pBx;
|
|
pgxy = -pgxy;
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
px = -px;
|
|
py = -py;
|
|
pEx = -pEx;
|
|
pBx = -pBx;
|
|
pgxz = -pgxz;
|
|
pEy = -pEy;
|
|
pBy = -pBy;
|
|
pgyz = -pgyz;
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
px = -px;
|
|
py = -py;
|
|
pz = -pz;
|
|
pEx = -pEx;
|
|
pEy = -pEy;
|
|
pEz = -pEz;
|
|
}
|
|
|
|
funcs(px, py, pz, pchi, pgxx, pgxy, pgxz, pgyy, pgyz, pgzz, pEx, pEy, pEz, pBx, pBy, pBz,
|
|
psi4RR, psi4II);
|
|
thetap = sqrt((2 * pl + 1.0) / 4.0 / PI) * misc::Wigner_d_function(pl, pm, spinw, costheta); // note the variation from -2 to 2
|
|
|
|
// find back the one
|
|
pchi = pchi + 1;
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap / pchi / pchi * (psi4RR * cosmphi + psi4II * sinmphi) * wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap / pchi / pchi * (psi4II * cosmphi - psi4RR * sinmphi) * wtcostheta[i];
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap / pchi / pchi * (psi4RR * cosmphi + psi4II * sinmphi);
|
|
IP_out[countlm] = IP_out[countlm] + thetap / pchi / pchi * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
}
|
|
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
#endif
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
#ifdef GaussInt
|
|
RP_out[ii] = RP_out[ii] * rex * dphi;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi;
|
|
#else
|
|
RP_out[ii] = RP_out[ii] * rex * dphi * dcostheta;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi * dcostheta;
|
|
#endif
|
|
}
|
|
//|------+ Communicate and sum the results from each processor.
|
|
|
|
{
|
|
double *RPIP_out = new double[2 * NN];
|
|
double *RPIP = new double[2 * NN];
|
|
memcpy(RPIP_out, RP_out, NN * sizeof(double));
|
|
memcpy(RPIP_out + NN, IP_out, NN * sizeof(double));
|
|
MPI_Allreduce(RPIP_out, RPIP, 2 * NN, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
|
memcpy(RP, RPIP, NN * sizeof(double));
|
|
memcpy(IP, RPIP + NN, NN * sizeof(double));
|
|
delete[] RPIP_out;
|
|
delete[] RPIP;
|
|
}
|
|
|
|
//|------= Free memory.
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
delete[] RP_out;
|
|
delete[] IP_out;
|
|
DG_List->clearList();
|
|
}
|
|
//|----------------------------------------------------------------
|
|
// for null shell patch2
|
|
//|----------------------------------------------------------------
|
|
// rex is x instead of r
|
|
void surface_integral::surf_Wave(double rex, int lev, NullShellPatch2 *GH, var *Rpsi4, var *Ipsi4,
|
|
int spinw, int maxl, int NN, double *RP, double *IP,
|
|
monitor *Monitor) // NN is the length of RP and IP
|
|
// spinw 0 for scalar; 1 for electricmagnetic wave; 2 for gravitaitonal wave
|
|
// we always assume spinw >= 0
|
|
{
|
|
const int InList = 2;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Rpsi4);
|
|
DG_List->insert(Ipsi4);
|
|
|
|
int n;
|
|
// since we used x instead of r, these global coordinates are fake
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
GH->Interp_Points_2D(DG_List, n_tot, pox, shellf, Symmetry);
|
|
|
|
int mp, Lp, Nmin, Nmax;
|
|
|
|
mp = n_tot / cpusize;
|
|
Lp = n_tot - cpusize * mp;
|
|
|
|
if (Lp > myrank)
|
|
{
|
|
Nmin = myrank * mp + myrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = myrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
//|~~~~~> Integrate the dot product of Dphi with the surface normal.
|
|
|
|
double *RP_out, *IP_out;
|
|
RP_out = new double[NN];
|
|
IP_out = new double[NN];
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
RP_out[ii] = 0;
|
|
IP_out[ii] = 0;
|
|
}
|
|
// theta part
|
|
double costheta, thetap;
|
|
double cosmphi, sinmphi;
|
|
|
|
int i, j;
|
|
int lpsy = 0;
|
|
if (Symmetry == 0)
|
|
lpsy = 1;
|
|
else if (Symmetry == 1)
|
|
lpsy = 2;
|
|
else if (Symmetry == 2)
|
|
lpsy = 8;
|
|
|
|
double psi4RR, psi4II;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
int countlm = 0;
|
|
for (int pl = spinw; pl < maxl + 1; pl++)
|
|
for (int pm = -pl; pm < pl + 1; pm++)
|
|
{
|
|
for (int lp = 0; lp < lpsy; lp++)
|
|
{
|
|
switch (lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = -shellf[InList * n + 1];
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = -shellf[InList * n + 1];
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = -shellf[InList * n + 1];
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = -shellf[InList * n + 1];
|
|
}
|
|
|
|
thetap = sqrt((2 * pl + 1.0) / 4.0 / PI) * misc::Wigner_d_function(pl, pm, spinw, costheta); // note the variation from -2 to 2
|
|
// based on Eq.(41) of PRD 77, 024027 (2008)
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap * (psi4RR * cosmphi + psi4II * sinmphi) * wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap * (psi4II * cosmphi - psi4RR * sinmphi) * wtcostheta[i];
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap * (psi4RR * cosmphi + psi4II * sinmphi); // + is because \bar of \bar{Y^s_lm} in Eq.(40)
|
|
// of PRD 77, 024027 (2008)
|
|
IP_out[countlm] = IP_out[countlm] + thetap * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
}
|
|
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
// do not need multiply with rex for null shell
|
|
#ifdef GaussInt
|
|
RP_out[ii] = RP_out[ii] * dphi;
|
|
IP_out[ii] = IP_out[ii] * dphi;
|
|
#else
|
|
RP_out[ii] = RP_out[ii] * dphi * dcostheta;
|
|
IP_out[ii] = IP_out[ii] * dphi * dcostheta;
|
|
#endif
|
|
}
|
|
//|------+ Communicate and sum the results from each processor.
|
|
|
|
{
|
|
double *RPIP_out = new double[2 * NN];
|
|
double *RPIP = new double[2 * NN];
|
|
memcpy(RPIP_out, RP_out, NN * sizeof(double));
|
|
memcpy(RPIP_out + NN, IP_out, NN * sizeof(double));
|
|
MPI_Allreduce(RPIP_out, RPIP, 2 * NN, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
|
memcpy(RP, RPIP, NN * sizeof(double));
|
|
memcpy(IP, RPIP + NN, NN * sizeof(double));
|
|
delete[] RPIP_out;
|
|
delete[] RPIP;
|
|
}
|
|
|
|
//|------= Free memory.
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
delete[] RP_out;
|
|
delete[] IP_out;
|
|
DG_List->clearList();
|
|
}
|
|
//|----------------------------------------------------------------
|
|
// for null shell patch
|
|
//|----------------------------------------------------------------
|
|
// rex is x instead of r
|
|
void surface_integral::surf_Wave(double rex, int lev, NullShellPatch *GH, var *Rpsi4, var *Ipsi4,
|
|
int spinw, int maxl, int NN, double *RP, double *IP,
|
|
monitor *Monitor) // NN is the length of RP and IP
|
|
// spinw 0 for scalar; 1 for electricmagnetic wave; 2 for gravitaitonal wave
|
|
// we always assume spinw >= 0
|
|
{
|
|
const int InList = 2;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Rpsi4);
|
|
DG_List->insert(Ipsi4);
|
|
|
|
int n;
|
|
// since we used x instead of r, these global coordinates are fake
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
GH->Interp_Points_2D(DG_List, n_tot, pox, shellf, Symmetry);
|
|
|
|
int mp, Lp, Nmin, Nmax;
|
|
|
|
mp = n_tot / cpusize;
|
|
Lp = n_tot - cpusize * mp;
|
|
|
|
if (Lp > myrank)
|
|
{
|
|
Nmin = myrank * mp + myrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = myrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
//|~~~~~> Integrate the dot product of Dphi with the surface normal.
|
|
|
|
double *RP_out, *IP_out;
|
|
RP_out = new double[NN];
|
|
IP_out = new double[NN];
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
RP_out[ii] = 0;
|
|
IP_out[ii] = 0;
|
|
}
|
|
// theta part
|
|
double costheta, thetap;
|
|
double cosmphi, sinmphi;
|
|
|
|
int i, j;
|
|
int lpsy = 0;
|
|
if (Symmetry == 0)
|
|
lpsy = 1;
|
|
else if (Symmetry == 1)
|
|
lpsy = 2;
|
|
else if (Symmetry == 2)
|
|
lpsy = 8;
|
|
|
|
double psi4RR, psi4II;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
int countlm = 0;
|
|
for (int pl = spinw; pl < maxl + 1; pl++)
|
|
for (int pm = -pl; pm < pl + 1; pm++)
|
|
{
|
|
for (int lp = 0; lp < lpsy; lp++)
|
|
{
|
|
switch (lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = -shellf[InList * n + 1];
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = -shellf[InList * n + 1];
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = -shellf[InList * n + 1];
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = shellf[InList * n + 1];
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
psi4RR = shellf[InList * n];
|
|
psi4II = -shellf[InList * n + 1];
|
|
}
|
|
|
|
thetap = sqrt((2 * pl + 1.0) / 4.0 / PI) * misc::Wigner_d_function(pl, pm, spinw, costheta); // note the variation from -2 to 2
|
|
// based on Eq.(41) of PRD 77, 024027 (2008)
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap * (psi4RR * cosmphi + psi4II * sinmphi) * wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap * (psi4II * cosmphi - psi4RR * sinmphi) * wtcostheta[i];
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap * (psi4RR * cosmphi + psi4II * sinmphi); // + is because \bar of \bar{Y^s_lm} in Eq.(40)
|
|
// of PRD 77, 024027 (2008)
|
|
IP_out[countlm] = IP_out[countlm] + thetap * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
}
|
|
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
// do not need multiply with rex for null shell
|
|
#ifdef GaussInt
|
|
RP_out[ii] = RP_out[ii] * dphi;
|
|
IP_out[ii] = IP_out[ii] * dphi;
|
|
#else
|
|
RP_out[ii] = RP_out[ii] * dphi * dcostheta;
|
|
IP_out[ii] = IP_out[ii] * dphi * dcostheta;
|
|
#endif
|
|
}
|
|
//|------+ Communicate and sum the results from each processor.
|
|
|
|
{
|
|
double *RPIP_out = new double[2 * NN];
|
|
double *RPIP = new double[2 * NN];
|
|
memcpy(RPIP_out, RP_out, NN * sizeof(double));
|
|
memcpy(RPIP_out + NN, IP_out, NN * sizeof(double));
|
|
MPI_Allreduce(RPIP_out, RPIP, 2 * NN, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
|
memcpy(RP, RPIP, NN * sizeof(double));
|
|
memcpy(IP, RPIP + NN, NN * sizeof(double));
|
|
delete[] RPIP_out;
|
|
delete[] RPIP;
|
|
}
|
|
|
|
//|------= Free memory.
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
delete[] RP_out;
|
|
delete[] IP_out;
|
|
DG_List->clearList();
|
|
}
|
|
//|----------------------------------------------------
|
|
//|
|
|
//| ADM mass, linear momentum and angular momentum
|
|
//|
|
|
//|----------------------------------------------------
|
|
void surface_integral::surf_MassPAng(double rex, int lev, cgh *GH, var *chi, var *trK,
|
|
var *gxx, var *gxy, var *gxz, var *gyy, var *gyz, var *gzz,
|
|
var *Axx, var *Axy, var *Axz, var *Ayy, var *Ayz, var *Azz,
|
|
var *Gmx, var *Gmy, var *Gmz,
|
|
var *Sfx_rhs, var *Sfy_rhs, var *Sfz_rhs, // temparay memory for mass^i
|
|
double *Rout, monitor *Monitor)
|
|
{
|
|
if (myrank == 0 && GH->grids[lev] != 1)
|
|
if (Monitor && Monitor->outfile)
|
|
Monitor->outfile << "WARNING: surface integral on multipatches" << endl;
|
|
else
|
|
cout << "WARNING: surface integral on multipatches" << endl;
|
|
|
|
double mass, px, py, pz, sx, sy, sz;
|
|
|
|
MyList<Patch> *Pp = GH->PatL[lev];
|
|
while (Pp)
|
|
{
|
|
MyList<Block> *BP = Pp->data->blb;
|
|
while (BP)
|
|
{
|
|
Block *cg = BP->data;
|
|
if (myrank == cg->rank)
|
|
{
|
|
f_admmass_bssn(cg->shape, cg->X[0], cg->X[1], cg->X[2],
|
|
cg->fgfs[chi->sgfn], cg->fgfs[trK->sgfn],
|
|
cg->fgfs[gxx->sgfn], cg->fgfs[gxy->sgfn], cg->fgfs[gxz->sgfn], cg->fgfs[gyy->sgfn], cg->fgfs[gyz->sgfn], cg->fgfs[gzz->sgfn],
|
|
cg->fgfs[Axx->sgfn], cg->fgfs[Axy->sgfn], cg->fgfs[Axz->sgfn], cg->fgfs[Ayy->sgfn], cg->fgfs[Ayz->sgfn], cg->fgfs[Azz->sgfn],
|
|
cg->fgfs[Gmx->sgfn], cg->fgfs[Gmy->sgfn], cg->fgfs[Gmz->sgfn],
|
|
cg->fgfs[Sfx_rhs->sgfn], cg->fgfs[Sfy_rhs->sgfn], cg->fgfs[Sfz_rhs->sgfn],
|
|
Symmetry);
|
|
}
|
|
if (BP == Pp->data->ble)
|
|
break;
|
|
BP = BP->next;
|
|
}
|
|
Pp = Pp->next;
|
|
}
|
|
|
|
const int InList = 17;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Sfx_rhs);
|
|
DG_List->insert(Sfy_rhs);
|
|
DG_List->insert(Sfz_rhs);
|
|
DG_List->insert(chi);
|
|
DG_List->insert(trK);
|
|
DG_List->insert(gxx);
|
|
DG_List->insert(gxy);
|
|
DG_List->insert(gxz);
|
|
DG_List->insert(gyy);
|
|
DG_List->insert(gyz);
|
|
DG_List->insert(gzz);
|
|
DG_List->insert(Axx);
|
|
DG_List->insert(Axy);
|
|
DG_List->insert(Axz);
|
|
DG_List->insert(Ayy);
|
|
DG_List->insert(Ayz);
|
|
DG_List->insert(Azz);
|
|
|
|
int n;
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
int mp, Lp, Nmin, Nmax;
|
|
mp = n_tot / cpusize;
|
|
Lp = n_tot - cpusize * mp;
|
|
if (Lp > myrank)
|
|
{
|
|
Nmin = myrank * mp + myrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = myrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
// we have assumed there is only one box on this level,
|
|
// so we do not need loop boxes
|
|
GH->PatL[lev]->data->Interp_Points(DG_List, n_tot, pox, shellf, Symmetry, Nmin, Nmax);
|
|
|
|
double Mass_out = 0;
|
|
double ang_outx, ang_outy, ang_outz;
|
|
double p_outx, p_outy, p_outz;
|
|
ang_outx = ang_outy = ang_outz = 0.0;
|
|
p_outx = p_outy = p_outz = 0.0;
|
|
const double f1o8 = 0.125;
|
|
|
|
double Chi, Psi;
|
|
double Gxx, Gxy, Gxz, Gyy, Gyz, Gzz;
|
|
double gupxx, gupxy, gupxz, gupyy, gupyz, gupzz;
|
|
double TRK, axx, axy, axz, ayy, ayz, azz;
|
|
double aupxx, aupxy, aupxz, aupyx, aupyy, aupyz, aupzx, aupzy, aupzz;
|
|
int i;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
|
|
Chi = shellf[InList * n + 3]; // chi in fact
|
|
TRK = shellf[InList * n + 4];
|
|
Gxx = shellf[InList * n + 5] + 1.0;
|
|
Gxy = shellf[InList * n + 6];
|
|
Gxz = shellf[InList * n + 7];
|
|
Gyy = shellf[InList * n + 8] + 1.0;
|
|
Gyz = shellf[InList * n + 9];
|
|
Gzz = shellf[InList * n + 10] + 1.0;
|
|
axx = shellf[InList * n + 11];
|
|
axy = shellf[InList * n + 12];
|
|
axz = shellf[InList * n + 13];
|
|
ayy = shellf[InList * n + 14];
|
|
ayz = shellf[InList * n + 15];
|
|
azz = shellf[InList * n + 16];
|
|
|
|
Chi = 1.0 / (1.0 + Chi); // exp(4*phi)
|
|
Psi = Chi * sqrt(Chi); // Psi^6
|
|
|
|
// Chi^2 corresponds to metric determinant
|
|
// but this factor has been considered in f_admmass_bssn
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
Mass_out = Mass_out + (shellf[InList * n] * nx_g[n] + shellf[InList * n + 1] * ny_g[n] + shellf[InList * n + 2] * nz_g[n]) * wtcostheta[i];
|
|
#else
|
|
Mass_out = Mass_out + (shellf[InList * n] * nx_g[n] + shellf[InList * n + 1] * ny_g[n] + shellf[InList * n + 2] * nz_g[n]);
|
|
#endif
|
|
|
|
gupzz = Gxx * Gyy * Gzz + Gxy * Gyz * Gxz + Gxz * Gxy * Gyz -
|
|
Gxz * Gyy * Gxz - Gxy * Gxy * Gzz - Gxx * Gyz * Gyz;
|
|
gupxx = (Gyy * Gzz - Gyz * Gyz) / gupzz;
|
|
gupxy = -(Gxy * Gzz - Gyz * Gxz) / gupzz;
|
|
gupxz = (Gxy * Gyz - Gyy * Gxz) / gupzz;
|
|
gupyy = (Gxx * Gzz - Gxz * Gxz) / gupzz;
|
|
gupyz = -(Gxx * Gyz - Gxy * Gxz) / gupzz;
|
|
gupzz = (Gxx * Gyy - Gxy * Gxy) / gupzz;
|
|
|
|
aupxx = gupxx * axx + gupxy * axy + gupxz * axz;
|
|
aupxy = gupxx * axy + gupxy * ayy + gupxz * ayz;
|
|
aupxz = gupxx * axz + gupxy * ayz + gupxz * azz;
|
|
aupyx = gupxy * axx + gupyy * axy + gupyz * axz;
|
|
aupyy = gupxy * axy + gupyy * ayy + gupyz * ayz;
|
|
aupyz = gupxy * axz + gupyy * ayz + gupyz * azz;
|
|
aupzx = gupxz * axx + gupyz * axy + gupzz * axz;
|
|
aupzy = gupxz * axy + gupyz * ayy + gupzz * ayz;
|
|
aupzz = gupxz * axz + gupyz * ayz + gupzz * azz;
|
|
if (Symmetry == 0)
|
|
{
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
// 1/8\pi \int \psi^6 (y A^m_z - zA^m_y) dS_m
|
|
ang_outx = ang_outx + f1o8 * Psi * (nx_g[n] * (pox[1][n] * aupxz - pox[2][n] * aupxy) + ny_g[n] * (pox[1][n] * aupyz - pox[2][n] * aupyy) + nz_g[n] * (pox[1][n] * aupzz - pox[2][n] * aupzy)) * wtcostheta[i];
|
|
// 1/8\pi \int \psi^6 (z A^m_x - xA^m_z) dS_m
|
|
ang_outy = ang_outy + f1o8 * Psi * (nx_g[n] * (pox[2][n] * aupxx - pox[0][n] * aupxz) + ny_g[n] * (pox[2][n] * aupyx - pox[0][n] * aupyz) + nz_g[n] * (pox[2][n] * aupzx - pox[0][n] * aupzz)) * wtcostheta[i];
|
|
// 1/8\pi \int \psi^6 (x A^m_y - yA^m_x) dS_m
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx)) * wtcostheta[i];
|
|
#else
|
|
// 1/8\pi \int \psi^6 (y A^m_z - zA^m_y) dS_m
|
|
ang_outx = ang_outx + f1o8 * Psi * (nx_g[n] * (pox[1][n] * aupxz - pox[2][n] * aupxy) + ny_g[n] * (pox[1][n] * aupyz - pox[2][n] * aupyy) + nz_g[n] * (pox[1][n] * aupzz - pox[2][n] * aupzy));
|
|
// 1/8\pi \int \psi^6 (z A^m_x - xA^m_z) dS_m
|
|
ang_outy = ang_outy + f1o8 * Psi * (nx_g[n] * (pox[2][n] * aupxx - pox[0][n] * aupxz) + ny_g[n] * (pox[2][n] * aupyx - pox[0][n] * aupyz) + nz_g[n] * (pox[2][n] * aupzx - pox[0][n] * aupzz));
|
|
// 1/8\pi \int \psi^6 (x A^m_y - yA^m_x) dS_m
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx));
|
|
#endif
|
|
}
|
|
else if (Symmetry == 1)
|
|
{
|
|
#ifdef GaussInt
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx)) * wtcostheta[i];
|
|
#else
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx));
|
|
#endif
|
|
}
|
|
|
|
axx = Chi * (axx + Gxx * TRK / 3.0);
|
|
axy = Chi * (axy + Gxy * TRK / 3.0);
|
|
axz = Chi * (axz + Gxz * TRK / 3.0);
|
|
ayy = Chi * (ayy + Gyy * TRK / 3.0);
|
|
ayz = Chi * (ayz + Gyz * TRK / 3.0);
|
|
azz = Chi * (azz + Gzz * TRK / 3.0);
|
|
|
|
axx = axx - TRK;
|
|
ayy = ayy - TRK;
|
|
azz = azz - TRK;
|
|
|
|
// 1/8\pi \int \psi^6 (K_mi - \delta_mi trK) dS^m: lower index linear momentum
|
|
if (Symmetry == 0)
|
|
{
|
|
#ifdef GaussInt
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz) * wtcostheta[i];
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz) * wtcostheta[i];
|
|
p_outz = p_outz + f1o8 * Psi * (nx_g[n] * axz + ny_g[n] * ayz + nz_g[n] * azz) * wtcostheta[i];
|
|
#else
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz);
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz);
|
|
p_outz = p_outz + f1o8 * Psi * (nx_g[n] * axz + ny_g[n] * ayz + nz_g[n] * azz);
|
|
#endif
|
|
}
|
|
else if (Symmetry == 1)
|
|
{
|
|
#ifdef GaussInt
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz) * wtcostheta[i];
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz) * wtcostheta[i];
|
|
#else
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz);
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
{
|
|
double scalar_out[7] = {Mass_out, ang_outx, ang_outy, ang_outz, p_outx, p_outy, p_outz};
|
|
double scalar_in[7];
|
|
MPI_Allreduce(scalar_out, scalar_in, 7, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
|
mass = scalar_in[0]; sx = scalar_in[1]; sy = scalar_in[2]; sz = scalar_in[3];
|
|
px = scalar_in[4]; py = scalar_in[5]; pz = scalar_in[6];
|
|
}
|
|
|
|
#ifdef GaussInt
|
|
mass = mass * rex * rex * dphi * factor;
|
|
|
|
sx = sx * rex * rex * dphi * (1.0 / PI) * factor;
|
|
sy = sy * rex * rex * dphi * (1.0 / PI) * factor;
|
|
sz = sz * rex * rex * dphi * (1.0 / PI) * factor;
|
|
|
|
px = px * rex * rex * dphi * (1.0 / PI) * factor;
|
|
py = py * rex * rex * dphi * (1.0 / PI) * factor;
|
|
pz = pz * rex * rex * dphi * (1.0 / PI) * factor;
|
|
#else
|
|
mass = mass * rex * rex * dphi * dcostheta * factor;
|
|
|
|
sx = sx * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
sy = sy * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
sz = sz * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
|
|
px = px * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
py = py * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
pz = pz * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
#endif
|
|
|
|
Rout[0] = mass;
|
|
Rout[1] = px;
|
|
Rout[2] = py;
|
|
Rout[3] = pz;
|
|
Rout[4] = sx;
|
|
Rout[5] = sy;
|
|
Rout[6] = sz;
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
DG_List->clearList();
|
|
}
|
|
void surface_integral::surf_MassPAng(double rex, int lev, cgh *GH, var *chi, var *trK,
|
|
var *gxx, var *gxy, var *gxz, var *gyy, var *gyz, var *gzz,
|
|
var *Axx, var *Axy, var *Axz, var *Ayy, var *Ayz, var *Azz,
|
|
var *Gmx, var *Gmy, var *Gmz,
|
|
var *Sfx_rhs, var *Sfy_rhs, var *Sfz_rhs, // temparay memory for mass^i
|
|
double *Rout, monitor *Monitor, MPI_Comm Comm_here)
|
|
{
|
|
int lmyrank;
|
|
MPI_Comm_rank(Comm_here, &lmyrank);
|
|
if (lmyrank == 0 && GH->grids[lev] != 1)
|
|
if (Monitor && Monitor->outfile)
|
|
Monitor->outfile << "WARNING: surface integral on multipatches" << endl;
|
|
else
|
|
cout << "WARNING: surface integral on multipatches" << endl;
|
|
|
|
double mass, px, py, pz, sx, sy, sz;
|
|
|
|
MyList<Patch> *Pp = GH->PatL[lev];
|
|
while (Pp)
|
|
{
|
|
MyList<Block> *BP = Pp->data->blb;
|
|
while (BP)
|
|
{
|
|
Block *cg = BP->data;
|
|
if (myrank == cg->rank)
|
|
{
|
|
f_admmass_bssn(cg->shape, cg->X[0], cg->X[1], cg->X[2],
|
|
cg->fgfs[chi->sgfn], cg->fgfs[trK->sgfn],
|
|
cg->fgfs[gxx->sgfn], cg->fgfs[gxy->sgfn], cg->fgfs[gxz->sgfn], cg->fgfs[gyy->sgfn], cg->fgfs[gyz->sgfn], cg->fgfs[gzz->sgfn],
|
|
cg->fgfs[Axx->sgfn], cg->fgfs[Axy->sgfn], cg->fgfs[Axz->sgfn], cg->fgfs[Ayy->sgfn], cg->fgfs[Ayz->sgfn], cg->fgfs[Azz->sgfn],
|
|
cg->fgfs[Gmx->sgfn], cg->fgfs[Gmy->sgfn], cg->fgfs[Gmz->sgfn],
|
|
cg->fgfs[Sfx_rhs->sgfn], cg->fgfs[Sfy_rhs->sgfn], cg->fgfs[Sfz_rhs->sgfn],
|
|
Symmetry);
|
|
}
|
|
if (BP == Pp->data->ble)
|
|
break;
|
|
BP = BP->next;
|
|
}
|
|
Pp = Pp->next;
|
|
}
|
|
|
|
const int InList = 17;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Sfx_rhs);
|
|
DG_List->insert(Sfy_rhs);
|
|
DG_List->insert(Sfz_rhs);
|
|
DG_List->insert(chi);
|
|
DG_List->insert(trK);
|
|
DG_List->insert(gxx);
|
|
DG_List->insert(gxy);
|
|
DG_List->insert(gxz);
|
|
DG_List->insert(gyy);
|
|
DG_List->insert(gyz);
|
|
DG_List->insert(gzz);
|
|
DG_List->insert(Axx);
|
|
DG_List->insert(Axy);
|
|
DG_List->insert(Axz);
|
|
DG_List->insert(Ayy);
|
|
DG_List->insert(Ayz);
|
|
DG_List->insert(Azz);
|
|
|
|
int n;
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
// we have assumed there is only one box on this level,
|
|
// so we do not need loop boxes
|
|
|
|
GH->PatL[lev]->data->Interp_Points(DG_List, n_tot, pox, shellf, Symmetry, Comm_here);
|
|
|
|
double Mass_out = 0;
|
|
double ang_outx, ang_outy, ang_outz;
|
|
double p_outx, p_outy, p_outz;
|
|
ang_outx = ang_outy = ang_outz = 0.0;
|
|
p_outx = p_outy = p_outz = 0.0;
|
|
const double f1o8 = 0.125;
|
|
|
|
int mp, Lp, Nmin, Nmax;
|
|
|
|
int cpusize_here;
|
|
MPI_Comm_size(Comm_here, &cpusize_here);
|
|
|
|
mp = n_tot / cpusize_here;
|
|
Lp = n_tot - cpusize_here * mp;
|
|
|
|
if (Lp > lmyrank)
|
|
{
|
|
Nmin = lmyrank * mp + lmyrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = lmyrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
double Chi, Psi;
|
|
double Gxx, Gxy, Gxz, Gyy, Gyz, Gzz;
|
|
double gupxx, gupxy, gupxz, gupyy, gupyz, gupzz;
|
|
double TRK, axx, axy, axz, ayy, ayz, azz;
|
|
double aupxx, aupxy, aupxz, aupyx, aupyy, aupyz, aupzx, aupzy, aupzz;
|
|
int i;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
|
|
Chi = shellf[InList * n + 3]; // chi in fact
|
|
TRK = shellf[InList * n + 4];
|
|
Gxx = shellf[InList * n + 5] + 1.0;
|
|
Gxy = shellf[InList * n + 6];
|
|
Gxz = shellf[InList * n + 7];
|
|
Gyy = shellf[InList * n + 8] + 1.0;
|
|
Gyz = shellf[InList * n + 9];
|
|
Gzz = shellf[InList * n + 10] + 1.0;
|
|
axx = shellf[InList * n + 11];
|
|
axy = shellf[InList * n + 12];
|
|
axz = shellf[InList * n + 13];
|
|
ayy = shellf[InList * n + 14];
|
|
ayz = shellf[InList * n + 15];
|
|
azz = shellf[InList * n + 16];
|
|
|
|
Chi = 1.0 / (1.0 + Chi); // exp(4*phi)
|
|
Psi = Chi * sqrt(Chi); // Psi^6
|
|
|
|
// Chi^2 corresponds to metric determinant
|
|
// but this factor has been considered in f_admmass_bssn
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
Mass_out = Mass_out + (shellf[InList * n] * nx_g[n] + shellf[InList * n + 1] * ny_g[n] + shellf[InList * n + 2] * nz_g[n]) * wtcostheta[i];
|
|
#else
|
|
Mass_out = Mass_out + (shellf[InList * n] * nx_g[n] + shellf[InList * n + 1] * ny_g[n] + shellf[InList * n + 2] * nz_g[n]);
|
|
#endif
|
|
|
|
gupzz = Gxx * Gyy * Gzz + Gxy * Gyz * Gxz + Gxz * Gxy * Gyz -
|
|
Gxz * Gyy * Gxz - Gxy * Gxy * Gzz - Gxx * Gyz * Gyz;
|
|
gupxx = (Gyy * Gzz - Gyz * Gyz) / gupzz;
|
|
gupxy = -(Gxy * Gzz - Gyz * Gxz) / gupzz;
|
|
gupxz = (Gxy * Gyz - Gyy * Gxz) / gupzz;
|
|
gupyy = (Gxx * Gzz - Gxz * Gxz) / gupzz;
|
|
gupyz = -(Gxx * Gyz - Gxy * Gxz) / gupzz;
|
|
gupzz = (Gxx * Gyy - Gxy * Gxy) / gupzz;
|
|
|
|
aupxx = gupxx * axx + gupxy * axy + gupxz * axz;
|
|
aupxy = gupxx * axy + gupxy * ayy + gupxz * ayz;
|
|
aupxz = gupxx * axz + gupxy * ayz + gupxz * azz;
|
|
aupyx = gupxy * axx + gupyy * axy + gupyz * axz;
|
|
aupyy = gupxy * axy + gupyy * ayy + gupyz * ayz;
|
|
aupyz = gupxy * axz + gupyy * ayz + gupyz * azz;
|
|
aupzx = gupxz * axx + gupyz * axy + gupzz * axz;
|
|
aupzy = gupxz * axy + gupyz * ayy + gupzz * ayz;
|
|
aupzz = gupxz * axz + gupyz * ayz + gupzz * azz;
|
|
if (Symmetry == 0)
|
|
{
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
// 1/8\pi \int \psi^6 (y A^m_z - zA^m_y) dS_m
|
|
ang_outx = ang_outx + f1o8 * Psi * (nx_g[n] * (pox[1][n] * aupxz - pox[2][n] * aupxy) + ny_g[n] * (pox[1][n] * aupyz - pox[2][n] * aupyy) + nz_g[n] * (pox[1][n] * aupzz - pox[2][n] * aupzy)) * wtcostheta[i];
|
|
// 1/8\pi \int \psi^6 (z A^m_x - xA^m_z) dS_m
|
|
ang_outy = ang_outy + f1o8 * Psi * (nx_g[n] * (pox[2][n] * aupxx - pox[0][n] * aupxz) + ny_g[n] * (pox[2][n] * aupyx - pox[0][n] * aupyz) + nz_g[n] * (pox[2][n] * aupzx - pox[0][n] * aupzz)) * wtcostheta[i];
|
|
// 1/8\pi \int \psi^6 (x A^m_y - yA^m_x) dS_m
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx)) * wtcostheta[i];
|
|
#else
|
|
// 1/8\pi \int \psi^6 (y A^m_z - zA^m_y) dS_m
|
|
ang_outx = ang_outx + f1o8 * Psi * (nx_g[n] * (pox[1][n] * aupxz - pox[2][n] * aupxy) + ny_g[n] * (pox[1][n] * aupyz - pox[2][n] * aupyy) + nz_g[n] * (pox[1][n] * aupzz - pox[2][n] * aupzy));
|
|
// 1/8\pi \int \psi^6 (z A^m_x - xA^m_z) dS_m
|
|
ang_outy = ang_outy + f1o8 * Psi * (nx_g[n] * (pox[2][n] * aupxx - pox[0][n] * aupxz) + ny_g[n] * (pox[2][n] * aupyx - pox[0][n] * aupyz) + nz_g[n] * (pox[2][n] * aupzx - pox[0][n] * aupzz));
|
|
// 1/8\pi \int \psi^6 (x A^m_y - yA^m_x) dS_m
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx));
|
|
#endif
|
|
}
|
|
else if (Symmetry == 1)
|
|
{
|
|
#ifdef GaussInt
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx)) * wtcostheta[i];
|
|
#else
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx));
|
|
#endif
|
|
}
|
|
|
|
axx = Chi * (axx + Gxx * TRK / 3.0);
|
|
axy = Chi * (axy + Gxy * TRK / 3.0);
|
|
axz = Chi * (axz + Gxz * TRK / 3.0);
|
|
ayy = Chi * (ayy + Gyy * TRK / 3.0);
|
|
ayz = Chi * (ayz + Gyz * TRK / 3.0);
|
|
azz = Chi * (azz + Gzz * TRK / 3.0);
|
|
|
|
axx = axx - TRK;
|
|
ayy = ayy - TRK;
|
|
azz = azz - TRK;
|
|
|
|
// 1/8\pi \int \psi^6 (K_mi - \delta_mi trK) dS^m: lower index linear momentum
|
|
if (Symmetry == 0)
|
|
{
|
|
#ifdef GaussInt
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz) * wtcostheta[i];
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz) * wtcostheta[i];
|
|
p_outz = p_outz + f1o8 * Psi * (nx_g[n] * axz + ny_g[n] * ayz + nz_g[n] * azz) * wtcostheta[i];
|
|
#else
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz);
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz);
|
|
p_outz = p_outz + f1o8 * Psi * (nx_g[n] * axz + ny_g[n] * ayz + nz_g[n] * azz);
|
|
#endif
|
|
}
|
|
else if (Symmetry == 1)
|
|
{
|
|
#ifdef GaussInt
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz) * wtcostheta[i];
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz) * wtcostheta[i];
|
|
#else
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz);
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
{
|
|
double scalar_out[7] = {Mass_out, ang_outx, ang_outy, ang_outz, p_outx, p_outy, p_outz};
|
|
double scalar_in[7];
|
|
MPI_Allreduce(scalar_out, scalar_in, 7, MPI_DOUBLE, MPI_SUM, Comm_here);
|
|
mass = scalar_in[0]; sx = scalar_in[1]; sy = scalar_in[2]; sz = scalar_in[3];
|
|
px = scalar_in[4]; py = scalar_in[5]; pz = scalar_in[6];
|
|
}
|
|
|
|
#ifdef GaussInt
|
|
mass = mass * rex * rex * dphi * factor;
|
|
|
|
sx = sx * rex * rex * dphi * (1.0 / PI) * factor;
|
|
sy = sy * rex * rex * dphi * (1.0 / PI) * factor;
|
|
sz = sz * rex * rex * dphi * (1.0 / PI) * factor;
|
|
|
|
px = px * rex * rex * dphi * (1.0 / PI) * factor;
|
|
py = py * rex * rex * dphi * (1.0 / PI) * factor;
|
|
pz = pz * rex * rex * dphi * (1.0 / PI) * factor;
|
|
#else
|
|
mass = mass * rex * rex * dphi * dcostheta * factor;
|
|
|
|
sx = sx * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
sy = sy * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
sz = sz * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
|
|
px = px * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
py = py * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
pz = pz * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
#endif
|
|
|
|
Rout[0] = mass;
|
|
Rout[1] = px;
|
|
Rout[2] = py;
|
|
Rout[3] = pz;
|
|
Rout[4] = sx;
|
|
Rout[5] = sy;
|
|
Rout[6] = sz;
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
DG_List->clearList();
|
|
}
|
|
//|----------------------------------------------------------------
|
|
// for shell patch
|
|
//|----------------------------------------------------------------
|
|
void surface_integral::surf_MassPAng(double rex, int lev, ShellPatch *GH, var *chi, var *trK,
|
|
var *gxx, var *gxy, var *gxz, var *gyy, var *gyz, var *gzz,
|
|
var *Axx, var *Axy, var *Axz, var *Ayy, var *Ayz, var *Azz,
|
|
var *Gmx, var *Gmy, var *Gmz,
|
|
var *Sfx_rhs, var *Sfy_rhs, var *Sfz_rhs, // temparay memory for mass^i
|
|
double *Rout, monitor *Monitor)
|
|
{
|
|
if (lev != 0)
|
|
{
|
|
if (myrank == 0)
|
|
{
|
|
if (Monitor && Monitor->outfile)
|
|
Monitor->outfile << "WARNING: shell surface integral not on level 0" << endl;
|
|
else
|
|
cout << "WARNING: shell surface integral not on level 0" << endl;
|
|
}
|
|
return;
|
|
}
|
|
|
|
double mass, px, py, pz, sx, sy, sz;
|
|
|
|
MyList<ss_patch> *Pp = GH->PatL;
|
|
while (Pp)
|
|
{
|
|
MyList<Block> *BL = Pp->data->blb;
|
|
int fngfs = Pp->data->fngfs;
|
|
while (BL)
|
|
{
|
|
Block *cg = BL->data;
|
|
if (myrank == cg->rank)
|
|
{
|
|
f_admmass_bssn_ss(cg->shape, cg->X[0], cg->X[1], cg->X[2],
|
|
cg->fgfs[fngfs + ShellPatch::gx], cg->fgfs[fngfs + ShellPatch::gy], cg->fgfs[fngfs + ShellPatch::gz],
|
|
cg->fgfs[fngfs + ShellPatch::drhodx], cg->fgfs[fngfs + ShellPatch::drhody], cg->fgfs[fngfs + ShellPatch::drhodz],
|
|
cg->fgfs[fngfs + ShellPatch::dsigmadx], cg->fgfs[fngfs + ShellPatch::dsigmady], cg->fgfs[fngfs + ShellPatch::dsigmadz],
|
|
cg->fgfs[fngfs + ShellPatch::dRdx], cg->fgfs[fngfs + ShellPatch::dRdy], cg->fgfs[fngfs + ShellPatch::dRdz],
|
|
cg->fgfs[fngfs + ShellPatch::drhodxx], cg->fgfs[fngfs + ShellPatch::drhodxy], cg->fgfs[fngfs + ShellPatch::drhodxz],
|
|
cg->fgfs[fngfs + ShellPatch::drhodyy], cg->fgfs[fngfs + ShellPatch::drhodyz], cg->fgfs[fngfs + ShellPatch::drhodzz],
|
|
cg->fgfs[fngfs + ShellPatch::dsigmadxx], cg->fgfs[fngfs + ShellPatch::dsigmadxy], cg->fgfs[fngfs + ShellPatch::dsigmadxz],
|
|
cg->fgfs[fngfs + ShellPatch::dsigmadyy], cg->fgfs[fngfs + ShellPatch::dsigmadyz], cg->fgfs[fngfs + ShellPatch::dsigmadzz],
|
|
cg->fgfs[fngfs + ShellPatch::dRdxx], cg->fgfs[fngfs + ShellPatch::dRdxy], cg->fgfs[fngfs + ShellPatch::dRdxz],
|
|
cg->fgfs[fngfs + ShellPatch::dRdyy], cg->fgfs[fngfs + ShellPatch::dRdyz], cg->fgfs[fngfs + ShellPatch::dRdzz],
|
|
cg->fgfs[chi->sgfn], cg->fgfs[trK->sgfn],
|
|
cg->fgfs[gxx->sgfn], cg->fgfs[gxy->sgfn], cg->fgfs[gxz->sgfn], cg->fgfs[gyy->sgfn], cg->fgfs[gyz->sgfn], cg->fgfs[gzz->sgfn],
|
|
cg->fgfs[Axx->sgfn], cg->fgfs[Axy->sgfn], cg->fgfs[Axz->sgfn], cg->fgfs[Ayy->sgfn], cg->fgfs[Ayz->sgfn], cg->fgfs[Azz->sgfn],
|
|
cg->fgfs[Gmx->sgfn], cg->fgfs[Gmy->sgfn], cg->fgfs[Gmz->sgfn],
|
|
cg->fgfs[Sfx_rhs->sgfn], cg->fgfs[Sfy_rhs->sgfn], cg->fgfs[Sfz_rhs->sgfn],
|
|
Symmetry, Pp->data->sst);
|
|
}
|
|
if (BL == Pp->data->ble)
|
|
break;
|
|
BL = BL->next;
|
|
}
|
|
Pp = Pp->next;
|
|
}
|
|
|
|
const int InList = 17;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(Sfx_rhs);
|
|
DG_List->insert(Sfy_rhs);
|
|
DG_List->insert(Sfz_rhs);
|
|
DG_List->insert(chi);
|
|
DG_List->insert(trK);
|
|
DG_List->insert(gxx);
|
|
DG_List->insert(gxy);
|
|
DG_List->insert(gxz);
|
|
DG_List->insert(gyy);
|
|
DG_List->insert(gyz);
|
|
DG_List->insert(gzz);
|
|
DG_List->insert(Axx);
|
|
DG_List->insert(Axy);
|
|
DG_List->insert(Axz);
|
|
DG_List->insert(Ayy);
|
|
DG_List->insert(Ayz);
|
|
DG_List->insert(Azz);
|
|
|
|
int n;
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
// we have assumed there is only one box on this level,
|
|
// so we do not need loop boxes
|
|
GH->Interp_Points(DG_List, n_tot, pox, shellf, Symmetry);
|
|
|
|
double Mass_out = 0;
|
|
double ang_outx, ang_outy, ang_outz;
|
|
double p_outx, p_outy, p_outz;
|
|
ang_outx = ang_outy = ang_outz = 0.0;
|
|
p_outx = p_outy = p_outz = 0.0;
|
|
const double f1o8 = 0.125;
|
|
|
|
int mp, Lp, Nmin, Nmax;
|
|
|
|
mp = n_tot / cpusize;
|
|
Lp = n_tot - cpusize * mp;
|
|
|
|
if (Lp > myrank)
|
|
{
|
|
Nmin = myrank * mp + myrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = myrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
double Chi, Psi;
|
|
double Gxx, Gxy, Gxz, Gyy, Gyz, Gzz;
|
|
double gupxx, gupxy, gupxz, gupyy, gupyz, gupzz;
|
|
double TRK, axx, axy, axz, ayy, ayz, azz;
|
|
double aupxx, aupxy, aupxz, aupyx, aupyy, aupyz, aupzx, aupzy, aupzz;
|
|
int i;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
|
|
Chi = shellf[InList * n + 3]; // chi in fact
|
|
TRK = shellf[InList * n + 4];
|
|
Gxx = shellf[InList * n + 5] + 1.0;
|
|
Gxy = shellf[InList * n + 6];
|
|
Gxz = shellf[InList * n + 7];
|
|
Gyy = shellf[InList * n + 8] + 1.0;
|
|
Gyz = shellf[InList * n + 9];
|
|
Gzz = shellf[InList * n + 10] + 1.0;
|
|
axx = shellf[InList * n + 11];
|
|
axy = shellf[InList * n + 12];
|
|
axz = shellf[InList * n + 13];
|
|
ayy = shellf[InList * n + 14];
|
|
ayz = shellf[InList * n + 15];
|
|
azz = shellf[InList * n + 16];
|
|
|
|
Chi = 1.0 / (1.0 + Chi); // exp(4*phi)
|
|
Psi = Chi * sqrt(Chi); // Psi^6
|
|
// Chi^2 corresponds to metric determinant
|
|
// but this factor has been considered in f_admmass_bssn
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
Mass_out = Mass_out + (shellf[InList * n] * nx_g[n] + shellf[InList * n + 1] * ny_g[n] + shellf[InList * n + 2] * nz_g[n]) * wtcostheta[i];
|
|
#else
|
|
Mass_out = Mass_out + (shellf[InList * n] * nx_g[n] + shellf[InList * n + 1] * ny_g[n] + shellf[InList * n + 2] * nz_g[n]);
|
|
#endif
|
|
|
|
gupzz = Gxx * Gyy * Gzz + Gxy * Gyz * Gxz + Gxz * Gxy * Gyz -
|
|
Gxz * Gyy * Gxz - Gxy * Gxy * Gzz - Gxx * Gyz * Gyz;
|
|
gupxx = (Gyy * Gzz - Gyz * Gyz) / gupzz;
|
|
gupxy = -(Gxy * Gzz - Gyz * Gxz) / gupzz;
|
|
gupxz = (Gxy * Gyz - Gyy * Gxz) / gupzz;
|
|
gupyy = (Gxx * Gzz - Gxz * Gxz) / gupzz;
|
|
gupyz = -(Gxx * Gyz - Gxy * Gxz) / gupzz;
|
|
gupzz = (Gxx * Gyy - Gxy * Gxy) / gupzz;
|
|
|
|
aupxx = gupxx * axx + gupxy * axy + gupxz * axz;
|
|
aupxy = gupxx * axy + gupxy * ayy + gupxz * ayz;
|
|
aupxz = gupxx * axz + gupxy * ayz + gupxz * azz;
|
|
aupyx = gupxy * axx + gupyy * axy + gupyz * axz;
|
|
aupyy = gupxy * axy + gupyy * ayy + gupyz * ayz;
|
|
aupyz = gupxy * axz + gupyy * ayz + gupyz * azz;
|
|
aupzx = gupxz * axx + gupyz * axy + gupzz * axz;
|
|
aupzy = gupxz * axy + gupyz * ayy + gupzz * ayz;
|
|
aupzz = gupxz * axz + gupyz * ayz + gupzz * azz;
|
|
if (Symmetry == 0)
|
|
{
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
// 1/8\pi \int \psi^6 (y A^m_z - zA^m_y) dS_m
|
|
ang_outx = ang_outx + f1o8 * Psi * (nx_g[n] * (pox[1][n] * aupxz - pox[2][n] * aupxy) + ny_g[n] * (pox[1][n] * aupyz - pox[2][n] * aupyy) + nz_g[n] * (pox[1][n] * aupzz - pox[2][n] * aupzy)) * wtcostheta[i];
|
|
// 1/8\pi \int \psi^6 (z A^m_x - xA^m_z) dS_m
|
|
ang_outy = ang_outy + f1o8 * Psi * (nx_g[n] * (pox[2][n] * aupxx - pox[0][n] * aupxz) + ny_g[n] * (pox[2][n] * aupyx - pox[0][n] * aupyz) + nz_g[n] * (pox[2][n] * aupzx - pox[0][n] * aupzz)) * wtcostheta[i];
|
|
// 1/8\pi \int \psi^6 (x A^m_y - yA^m_x) dS_m
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx)) * wtcostheta[i];
|
|
#else
|
|
// 1/8\pi \int \psi^6 (y A^m_z - zA^m_y) dS_m
|
|
ang_outx = ang_outx + f1o8 * Psi * (nx_g[n] * (pox[1][n] * aupxz - pox[2][n] * aupxy) + ny_g[n] * (pox[1][n] * aupyz - pox[2][n] * aupyy) + nz_g[n] * (pox[1][n] * aupzz - pox[2][n] * aupzy));
|
|
// 1/8\pi \int \psi^6 (z A^m_x - xA^m_z) dS_m
|
|
ang_outy = ang_outy + f1o8 * Psi * (nx_g[n] * (pox[2][n] * aupxx - pox[0][n] * aupxz) + ny_g[n] * (pox[2][n] * aupyx - pox[0][n] * aupyz) + nz_g[n] * (pox[2][n] * aupzx - pox[0][n] * aupzz));
|
|
// 1/8\pi \int \psi^6 (x A^m_y - yA^m_x) dS_m
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx));
|
|
#endif
|
|
}
|
|
else if (Symmetry == 1)
|
|
{
|
|
#ifdef GaussInt
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx)) * wtcostheta[i];
|
|
#else
|
|
ang_outz = ang_outz + f1o8 * Psi * (nx_g[n] * (pox[0][n] * aupxy - pox[1][n] * aupxx) + ny_g[n] * (pox[0][n] * aupyy - pox[1][n] * aupyx) + nz_g[n] * (pox[0][n] * aupzy - pox[1][n] * aupzx));
|
|
#endif
|
|
}
|
|
|
|
axx = Chi * (axx + Gxx * TRK / 3.0);
|
|
axy = Chi * (axy + Gxy * TRK / 3.0);
|
|
axz = Chi * (axz + Gxz * TRK / 3.0);
|
|
ayy = Chi * (ayy + Gyy * TRK / 3.0);
|
|
ayz = Chi * (ayz + Gyz * TRK / 3.0);
|
|
azz = Chi * (azz + Gzz * TRK / 3.0);
|
|
|
|
axx = axx - TRK;
|
|
ayy = ayy - TRK;
|
|
azz = azz - TRK;
|
|
|
|
// 1/8\pi \int \psi^6 (K_mi - \delta_mi trK) dS^m: lower index linear momentum
|
|
if (Symmetry == 0)
|
|
{
|
|
#ifdef GaussInt
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz) * wtcostheta[i];
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz) * wtcostheta[i];
|
|
p_outz = p_outz + f1o8 * Psi * (nx_g[n] * axz + ny_g[n] * ayz + nz_g[n] * azz) * wtcostheta[i];
|
|
#else
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz);
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz);
|
|
p_outz = p_outz + f1o8 * Psi * (nx_g[n] * axz + ny_g[n] * ayz + nz_g[n] * azz);
|
|
#endif
|
|
}
|
|
else if (Symmetry == 1)
|
|
{
|
|
#ifdef GaussInt
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz) * wtcostheta[i];
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz) * wtcostheta[i];
|
|
#else
|
|
p_outx = p_outx + f1o8 * Psi * (nx_g[n] * axx + ny_g[n] * axy + nz_g[n] * axz);
|
|
p_outy = p_outy + f1o8 * Psi * (nx_g[n] * axy + ny_g[n] * ayy + nz_g[n] * ayz);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
{
|
|
double scalar_out[7] = {Mass_out, ang_outx, ang_outy, ang_outz, p_outx, p_outy, p_outz};
|
|
double scalar_in[7];
|
|
MPI_Allreduce(scalar_out, scalar_in, 7, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
|
mass = scalar_in[0]; sx = scalar_in[1]; sy = scalar_in[2]; sz = scalar_in[3];
|
|
px = scalar_in[4]; py = scalar_in[5]; pz = scalar_in[6];
|
|
}
|
|
|
|
#ifdef GaussInt
|
|
mass = mass * rex * rex * dphi * factor;
|
|
|
|
sx = sx * rex * rex * dphi * (1.0 / PI) * factor;
|
|
sy = sy * rex * rex * dphi * (1.0 / PI) * factor;
|
|
sz = sz * rex * rex * dphi * (1.0 / PI) * factor;
|
|
|
|
px = px * rex * rex * dphi * (1.0 / PI) * factor;
|
|
py = py * rex * rex * dphi * (1.0 / PI) * factor;
|
|
pz = pz * rex * rex * dphi * (1.0 / PI) * factor;
|
|
#else
|
|
mass = mass * rex * rex * dphi * dcostheta * factor;
|
|
|
|
sx = sx * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
sy = sy * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
sz = sz * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
|
|
px = px * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
py = py * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
pz = pz * rex * rex * dphi * dcostheta * (1.0 / PI) * factor;
|
|
#endif
|
|
|
|
Rout[0] = mass;
|
|
Rout[1] = px;
|
|
Rout[2] = py;
|
|
Rout[3] = pz;
|
|
Rout[4] = sx;
|
|
Rout[5] = sy;
|
|
Rout[6] = sz;
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
DG_List->clearList();
|
|
}
|
|
//|----------------------------------------------------------------
|
|
// do not discriminate box and shell
|
|
// for Gravitational wave specially symmetric case
|
|
//|----------------------------------------------------------------
|
|
void surface_integral::surf_Wave(double rex, cgh *GH, ShellPatch *SH,
|
|
var *chi, var *trK,
|
|
var *gxx, var *gxy, var *gxz, var *gyy, var *gyz, var *gzz,
|
|
var *Axx, var *Axy, var *Axz, var *Ayy, var *Ayz, var *Azz,
|
|
var *chix, var *chiy, var *chiz,
|
|
var *trKx, var *trKy, var *trKz,
|
|
var *Axxx, var *Axxy, var *Axxz,
|
|
var *Axyx, var *Axyy, var *Axyz,
|
|
var *Axzx, var *Axzy, var *Axzz,
|
|
var *Ayyx, var *Ayyy, var *Ayyz,
|
|
var *Ayzx, var *Ayzy, var *Ayzz,
|
|
var *Azzx, var *Azzy, var *Azzz,
|
|
var *Gamxxx, var *Gamxxy, var *Gamxxz, var *Gamxyy, var *Gamxyz, var *Gamxzz,
|
|
var *Gamyxx, var *Gamyxy, var *Gamyxz, var *Gamyyy, var *Gamyyz, var *Gamyzz,
|
|
var *Gamzxx, var *Gamzxy, var *Gamzxz, var *Gamzyy, var *Gamzyz, var *Gamzzz,
|
|
var *Rxx, var *Rxy, var *Rxz, var *Ryy, var *Ryz, var *Rzz,
|
|
int spinw, int maxl, int NN, double *RP, double *IP,
|
|
monitor *Monitor) // NN is the length of RP and IP
|
|
{
|
|
const int InList = 62;
|
|
|
|
MyList<var> *DG_List = new MyList<var>(chi);
|
|
DG_List->insert(trK);
|
|
DG_List->insert(gxx);
|
|
DG_List->insert(gxy);
|
|
DG_List->insert(gxz);
|
|
DG_List->insert(gyy);
|
|
DG_List->insert(gyz);
|
|
DG_List->insert(gzz);
|
|
DG_List->insert(Axx);
|
|
DG_List->insert(Axy);
|
|
DG_List->insert(Axz);
|
|
DG_List->insert(Ayy);
|
|
DG_List->insert(Ayz);
|
|
DG_List->insert(Azz);
|
|
DG_List->insert(chix);
|
|
DG_List->insert(chiy);
|
|
DG_List->insert(chiz);
|
|
DG_List->insert(trKx);
|
|
DG_List->insert(trKy);
|
|
DG_List->insert(trKz);
|
|
DG_List->insert(Axxx);
|
|
DG_List->insert(Axxy);
|
|
DG_List->insert(Axxz);
|
|
DG_List->insert(Axyx);
|
|
DG_List->insert(Axyy);
|
|
DG_List->insert(Axyz);
|
|
DG_List->insert(Axzx);
|
|
DG_List->insert(Axzy);
|
|
DG_List->insert(Axzz);
|
|
DG_List->insert(Ayyx);
|
|
DG_List->insert(Ayyy);
|
|
DG_List->insert(Ayyz);
|
|
DG_List->insert(Ayzx);
|
|
DG_List->insert(Ayzy);
|
|
DG_List->insert(Ayzz);
|
|
DG_List->insert(Azzx);
|
|
DG_List->insert(Azzy);
|
|
DG_List->insert(Azzz);
|
|
DG_List->insert(Gamxxx);
|
|
DG_List->insert(Gamxxy);
|
|
DG_List->insert(Gamxxz);
|
|
DG_List->insert(Gamxyy);
|
|
DG_List->insert(Gamxyz);
|
|
DG_List->insert(Gamxzz);
|
|
DG_List->insert(Gamyxx);
|
|
DG_List->insert(Gamyxy);
|
|
DG_List->insert(Gamyxz);
|
|
DG_List->insert(Gamyyy);
|
|
DG_List->insert(Gamyyz);
|
|
DG_List->insert(Gamyzz);
|
|
DG_List->insert(Gamzxx);
|
|
DG_List->insert(Gamzxy);
|
|
DG_List->insert(Gamzxz);
|
|
DG_List->insert(Gamzyy);
|
|
DG_List->insert(Gamzyz);
|
|
DG_List->insert(Gamzzz);
|
|
DG_List->insert(Rxx);
|
|
DG_List->insert(Rxy);
|
|
DG_List->insert(Rxz);
|
|
DG_List->insert(Ryy);
|
|
DG_List->insert(Ryz);
|
|
DG_List->insert(Rzz);
|
|
|
|
int n;
|
|
double *pox[3];
|
|
for (int i = 0; i < 3; i++)
|
|
pox[i] = new double[n_tot];
|
|
for (n = 0; n < n_tot; n++)
|
|
{
|
|
pox[0][n] = rex * nx_g[n];
|
|
pox[1][n] = rex * ny_g[n];
|
|
pox[2][n] = rex * nz_g[n];
|
|
}
|
|
|
|
double *shellf;
|
|
shellf = new double[n_tot * InList];
|
|
|
|
SR_Interp_Points(DG_List, GH, SH, n_tot, pox, shellf);
|
|
|
|
double *RP_out, *IP_out;
|
|
RP_out = new double[NN];
|
|
IP_out = new double[NN];
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
RP_out[ii] = 0;
|
|
IP_out[ii] = 0;
|
|
}
|
|
|
|
int mp, Lp, Nmin, Nmax;
|
|
|
|
mp = n_tot / cpusize;
|
|
Lp = n_tot - cpusize * mp;
|
|
|
|
if (Lp > myrank)
|
|
{
|
|
Nmin = myrank * mp + myrank;
|
|
Nmax = Nmin + mp;
|
|
}
|
|
else
|
|
{
|
|
Nmin = myrank * mp + Lp;
|
|
Nmax = Nmin + mp - 1;
|
|
}
|
|
|
|
// theta part
|
|
double costheta, thetap;
|
|
double cosmphi, sinmphi;
|
|
|
|
int i, j;
|
|
int lpsy = 0;
|
|
if (Symmetry == 0)
|
|
lpsy = 1;
|
|
else if (Symmetry == 1)
|
|
lpsy = 2;
|
|
else if (Symmetry == 2)
|
|
lpsy = 8;
|
|
|
|
double psi4RR, psi4II;
|
|
double px, py, pz;
|
|
double pchi, ptrK, pgxx, pgxy, pgxz, pgyy, pgyz, pgzz;
|
|
double pAxx, pAxy, pAxz, pAyy, pAyz, pAzz;
|
|
double pchix, pchiy, pchiz;
|
|
double ptrKx, ptrKy, ptrKz;
|
|
double pAxxx, pAxxy, pAxxz;
|
|
double pAxyx, pAxyy, pAxyz;
|
|
double pAxzx, pAxzy, pAxzz;
|
|
double pAyyx, pAyyy, pAyyz;
|
|
double pAyzx, pAyzy, pAyzz;
|
|
double pAzzx, pAzzy, pAzzz;
|
|
double pGamxxx, pGamxxy, pGamxxz, pGamxyy, pGamxyz, pGamxzz;
|
|
double pGamyxx, pGamyxy, pGamyxz, pGamyyy, pGamyyz, pGamyzz;
|
|
double pGamzxx, pGamzxy, pGamzxz, pGamzyy, pGamzyz, pGamzzz;
|
|
double pRxx, pRxy, pRxz, pRyy, pRyz, pRzz;
|
|
for (n = Nmin; n <= Nmax; n++)
|
|
{
|
|
// need round off always
|
|
i = int(n / N_phi); // int(1.723) = 1, int(-1.732) = -1
|
|
j = n - i * N_phi;
|
|
|
|
int countlm = 0;
|
|
for (int pl = spinw; pl < maxl + 1; pl++)
|
|
for (int pm = -pl; pm < pl + 1; pm++)
|
|
{
|
|
for (int lp = 0; lp < lpsy; lp++)
|
|
{
|
|
px = pox[0][n];
|
|
py = pox[1][n];
|
|
pz = pox[2][n];
|
|
pchi = shellf[InList * n];
|
|
ptrK = shellf[InList * n + 1];
|
|
pgxx = shellf[InList * n + 2];
|
|
pgxy = shellf[InList * n + 3];
|
|
pgxz = shellf[InList * n + 4];
|
|
pgyy = shellf[InList * n + 5];
|
|
pgyz = shellf[InList * n + 6];
|
|
pgzz = shellf[InList * n + 7];
|
|
pAxx = shellf[InList * n + 8];
|
|
pAxy = shellf[InList * n + 9];
|
|
pAxz = shellf[InList * n + 10];
|
|
pAyy = shellf[InList * n + 11];
|
|
pAyz = shellf[InList * n + 12];
|
|
pAzz = shellf[InList * n + 13];
|
|
pchix = shellf[InList * n + 14];
|
|
pchiy = shellf[InList * n + 15];
|
|
pchiz = shellf[InList * n + 16];
|
|
ptrKx = shellf[InList * n + 17];
|
|
ptrKy = shellf[InList * n + 18];
|
|
ptrKz = shellf[InList * n + 19];
|
|
pAxxx = shellf[InList * n + 20];
|
|
pAxxy = shellf[InList * n + 21];
|
|
pAxxz = shellf[InList * n + 22];
|
|
pAxyx = shellf[InList * n + 23];
|
|
pAxyy = shellf[InList * n + 24];
|
|
pAxyz = shellf[InList * n + 25];
|
|
pAxzx = shellf[InList * n + 26];
|
|
pAxzy = shellf[InList * n + 27];
|
|
pAxzz = shellf[InList * n + 28];
|
|
pAyyx = shellf[InList * n + 29];
|
|
pAyyy = shellf[InList * n + 30];
|
|
pAyyz = shellf[InList * n + 31];
|
|
pAyzx = shellf[InList * n + 32];
|
|
pAyzy = shellf[InList * n + 33];
|
|
pAyzz = shellf[InList * n + 34];
|
|
pAzzx = shellf[InList * n + 35];
|
|
pAzzy = shellf[InList * n + 36];
|
|
pAzzz = shellf[InList * n + 37];
|
|
pGamxxx = shellf[InList * n + 38];
|
|
pGamxxy = shellf[InList * n + 39];
|
|
pGamxxz = shellf[InList * n + 40];
|
|
pGamxyy = shellf[InList * n + 41];
|
|
pGamxyz = shellf[InList * n + 42];
|
|
pGamxzz = shellf[InList * n + 43];
|
|
pGamyxx = shellf[InList * n + 44];
|
|
pGamyxy = shellf[InList * n + 45];
|
|
pGamyxz = shellf[InList * n + 46];
|
|
pGamyyy = shellf[InList * n + 47];
|
|
pGamyyz = shellf[InList * n + 48];
|
|
pGamyzz = shellf[InList * n + 49];
|
|
pGamzxx = shellf[InList * n + 50];
|
|
pGamzxy = shellf[InList * n + 51];
|
|
pGamzxz = shellf[InList * n + 52];
|
|
pGamzyy = shellf[InList * n + 53];
|
|
pGamzyz = shellf[InList * n + 54];
|
|
pGamzzz = shellf[InList * n + 55];
|
|
pRxx = shellf[InList * n + 56];
|
|
pRxy = shellf[InList * n + 57];
|
|
pRxz = shellf[InList * n + 58];
|
|
pRyy = shellf[InList * n + 59];
|
|
pRyz = shellf[InList * n + 60];
|
|
pRzz = shellf[InList * n + 61];
|
|
switch (lp)
|
|
{
|
|
case 0: //+++ (theta, phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
break;
|
|
case 1: //++- (pi-theta, phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = sin(pm * (j + 0.5) * dphi);
|
|
pz = -pz;
|
|
pgxz = -pgxz;
|
|
pgyz = -pgyz;
|
|
pAxz = -pAxz;
|
|
pAyz = -pAyz;
|
|
pchiz = -pchiz;
|
|
ptrKz = -ptrKz;
|
|
pAxxz = -pAxxz;
|
|
pAxyz = -pAxyz;
|
|
pAxzx = -pAxzx;
|
|
pAxzy = -pAxzy;
|
|
pAyyz = -pAyyz;
|
|
pAyzx = -pAyzx;
|
|
pAyzy = -pAyzy;
|
|
pAzzz = -pAzzz;
|
|
pGamxxz = -pGamxxz;
|
|
pGamxyz = -pGamxyz;
|
|
pGamyxz = -pGamyxz;
|
|
pGamyyz = -pGamyyz;
|
|
pGamzxx = -pGamzxx;
|
|
pGamzxy = -pGamzxy;
|
|
pGamzyy = -pGamzyy;
|
|
pGamzzz = -pGamzzz;
|
|
pRxz = -pRxz;
|
|
pRyz = -pRyz;
|
|
break;
|
|
case 2: //+-+ (theta, 2*pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
py = -py;
|
|
pgxy = -pgxy;
|
|
pgyz = -pgyz;
|
|
pAxy = -pAxy;
|
|
pAyz = -pAyz;
|
|
pchiy = -pchiy;
|
|
ptrKy = -ptrKy;
|
|
pAxxy = -pAxxy;
|
|
pAxyx = -pAxyx;
|
|
pAxyz = -pAxyz;
|
|
pAxzy = -pAxzy;
|
|
pAyyy = -pAyyy;
|
|
pAyzx = -pAyzx;
|
|
pAyzz = -pAyzz;
|
|
pAzzy = -pAzzy;
|
|
pGamxxy = -pGamxxy;
|
|
pGamxyz = -pGamxyz;
|
|
pGamyxx = -pGamyxx;
|
|
pGamyxz = -pGamyxz;
|
|
pGamyyy = -pGamyyy;
|
|
pGamyzz = -pGamyzz;
|
|
pGamzxy = -pGamzxy;
|
|
pGamzyz = -pGamzyz;
|
|
pRxy = -pRxy;
|
|
pRyz = -pRyz;
|
|
break;
|
|
case 3: //+-- (pi-theta, 2*pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (j + 0.5) * dphi);
|
|
sinmphi = -sin(pm * (j + 0.5) * dphi);
|
|
py = -py;
|
|
pz = -pz;
|
|
pgxy = -pgxy;
|
|
pgxz = -pgxz;
|
|
pAxy = -pAxy;
|
|
pAxz = -pAxz;
|
|
pchiy = -pchiy;
|
|
pchiz = -pchiz;
|
|
ptrKy = -ptrKy;
|
|
ptrKz = -ptrKz;
|
|
pAxxy = -pAxxy;
|
|
pAxxz = -pAxxz;
|
|
pAxyx = -pAxyx;
|
|
pAxzx = -pAxzx;
|
|
pAyyy = -pAyyy;
|
|
pAyyz = -pAyyz;
|
|
pAyzy = -pAyzy;
|
|
pAyzz = -pAyzz;
|
|
pAzzy = -pAzzy;
|
|
pAzzz = -pAzzz;
|
|
pGamxxy = -pGamxxy;
|
|
pGamxxz = -pGamxxz;
|
|
pGamyxx = -pGamyxx;
|
|
pGamyyy = -pGamyyy;
|
|
pGamyyz = -pGamyyz;
|
|
pGamyzz = -pGamyzz;
|
|
pGamzxx = -pGamzxx;
|
|
pGamzyy = -pGamzyy;
|
|
pGamzyz = -pGamzyz;
|
|
pGamzzz = -pGamzzz;
|
|
pRxy = -pRxy;
|
|
pRxz = -pRxz;
|
|
break;
|
|
case 4: //-++ (theta, pi-phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
px = -px;
|
|
pgxy = -pgxy;
|
|
pgxz = -pgxz;
|
|
pAxy = -pAxy;
|
|
pAxz = -pAxz;
|
|
pchix = -pchix;
|
|
ptrKx = -ptrKx;
|
|
pAxxx = -pAxxx;
|
|
pAxyy = -pAxyy;
|
|
pAxyz = -pAxyz;
|
|
pAxzy = -pAxzy;
|
|
pAxzz = -pAxzz;
|
|
pAyyx = -pAyyx;
|
|
pAyzx = -pAyzx;
|
|
pAzzx = -pAzzx;
|
|
pGamxxx = -pGamxxx;
|
|
pGamxyy = -pGamxyy;
|
|
pGamxyz = -pGamxyz;
|
|
pGamxzz = -pGamxzz;
|
|
pGamyxy = -pGamyxy;
|
|
pGamyxz = -pGamyxz;
|
|
pGamzxy = -pGamzxy;
|
|
pGamzxz = -pGamzxz;
|
|
pRxy = -pRxy;
|
|
pRxz = -pRxz;
|
|
break;
|
|
case 5: //-+- (pi-theta, pi-phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI - (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI - (j + 0.5) * dphi));
|
|
px = -px;
|
|
pz = -pz;
|
|
pgxy = -pgxy;
|
|
pgyz = -pgyz;
|
|
pAxy = -pAxy;
|
|
pAyz = -pAyz;
|
|
pchix = -pchix;
|
|
pchiz = -pchiz;
|
|
ptrKx = -ptrKx;
|
|
ptrKz = -ptrKz;
|
|
pAxxx = -pAxxx;
|
|
pAxxz = -pAxxz;
|
|
pAxyy = -pAxyy;
|
|
pAxzx = -pAxzx;
|
|
pAxzz = -pAxzz;
|
|
pAyyx = -pAyyx;
|
|
pAyyz = -pAyyz;
|
|
pAyzy = -pAyzy;
|
|
pAzzx = -pAzzx;
|
|
pAzzz = -pAzzz;
|
|
pGamxxx = -pGamxxx;
|
|
pGamxxz = -pGamxxz;
|
|
pGamxyy = -pGamxyy;
|
|
pGamxzz = -pGamxzz;
|
|
pGamyxy = -pGamyxy;
|
|
pGamyyz = -pGamyyz;
|
|
pGamzxx = -pGamzxx;
|
|
pGamzxz = -pGamzxz;
|
|
pGamzyy = -pGamzyy;
|
|
pGamzzz = -pGamzzz;
|
|
pRxy = -pRxy;
|
|
pRyz = -pRyz;
|
|
break;
|
|
case 6: //--+ (theta, pi+phi)
|
|
costheta = arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
px = -px;
|
|
py = -py;
|
|
pgxz = -pgxz;
|
|
pgyz = -pgyz;
|
|
pAxz = -pAxz;
|
|
pAyz = -pAyz;
|
|
pchix = -pchix;
|
|
pchiy = -pchiy;
|
|
ptrKx = -ptrKx;
|
|
ptrKy = -ptrKy;
|
|
pAxxx = -pAxxx;
|
|
pAxxy = -pAxxy;
|
|
pAxyx = -pAxyx;
|
|
pAxyy = -pAxyy;
|
|
pAxzz = -pAxzz;
|
|
pAyyx = -pAyyx;
|
|
pAyyy = -pAyyy;
|
|
pAyzz = -pAyzz;
|
|
pAzzx = -pAzzx;
|
|
pAzzy = -pAzzy;
|
|
pGamxxx = -pGamxxx;
|
|
pGamxxy = -pGamxxy;
|
|
pGamxyy = -pGamxyy;
|
|
pGamxzz = -pGamxzz;
|
|
pGamyxx = -pGamyxx;
|
|
pGamyxy = -pGamyxy;
|
|
pGamyyy = -pGamyyy;
|
|
pGamyzz = -pGamyzz;
|
|
pGamzxz = -pGamzxz;
|
|
pGamzyz = -pGamzyz;
|
|
pRxz = -pRxz;
|
|
pRyz = -pRyz;
|
|
break;
|
|
case 7: //--- (pi-theta, pi+phi)
|
|
costheta = -arcostheta[i];
|
|
cosmphi = cos(pm * (PI + (j + 0.5) * dphi));
|
|
sinmphi = sin(pm * (PI + (j + 0.5) * dphi));
|
|
px = -px;
|
|
py = -py;
|
|
pz = -pz;
|
|
pchix = -pchix;
|
|
pchiy = -pchiy;
|
|
pchiz = -pchiz;
|
|
ptrKx = -ptrKx;
|
|
ptrKy = -ptrKy;
|
|
ptrKz = -ptrKz;
|
|
pAxxx = -pAxxx;
|
|
pAxxy = -pAxxy;
|
|
pAxxz = -pAxxz;
|
|
pAxyx = -pAxyx;
|
|
pAxyy = -pAxyy;
|
|
pAxyz = -pAxyz;
|
|
pAxzx = -pAxzx;
|
|
pAxzy = -pAxzy;
|
|
pAxzz = -pAxzz;
|
|
pAyyx = -pAyyx;
|
|
pAyyy = -pAyyy;
|
|
pAyyz = -pAyyz;
|
|
pAyzx = -pAyzx;
|
|
pAyzy = -pAyzy;
|
|
pAyzz = -pAyzz;
|
|
pAzzx = -pAzzx;
|
|
pAzzy = -pAzzy;
|
|
pAzzz = -pAzzz;
|
|
pGamxxx = -pGamxxx;
|
|
pGamxxy = -pGamxxy;
|
|
pGamxxz = -pGamxxz;
|
|
pGamxyy = -pGamxyy;
|
|
pGamxyz = -pGamxyz;
|
|
pGamxzz = -pGamxzz;
|
|
pGamyxx = -pGamyxx;
|
|
pGamyxy = -pGamyxy;
|
|
pGamyxz = -pGamyxz;
|
|
pGamyyy = -pGamyyy;
|
|
pGamyyz = -pGamyyz;
|
|
pGamyzz = -pGamyzz;
|
|
pGamzxx = -pGamzxx;
|
|
pGamzxy = -pGamzxy;
|
|
pGamzxz = -pGamzxz;
|
|
pGamzyy = -pGamzyy;
|
|
pGamzyz = -pGamzyz;
|
|
pGamzzz = -pGamzzz;
|
|
}
|
|
|
|
f_getnp4_point(px, py, pz, pchi, ptrK,
|
|
pgxx, pgxy, pgxz, pgyy, pgyz, pgzz,
|
|
pAxx, pAxy, pAxz, pAyy, pAyz, pAzz,
|
|
pchix, pchiy, pchiz,
|
|
ptrKx, ptrKy, ptrKz,
|
|
pAxxx, pAxxy, pAxxz,
|
|
pAxyx, pAxyy, pAxyz,
|
|
pAxzx, pAxzy, pAxzz,
|
|
pAyyx, pAyyy, pAyyz,
|
|
pAyzx, pAyzy, pAyzz,
|
|
pAzzx, pAzzy, pAzzz,
|
|
pGamxxx, pGamxxy, pGamxxz, pGamxyy, pGamxyz, pGamxzz,
|
|
pGamyxx, pGamyxy, pGamyxz, pGamyyy, pGamyyz, pGamyzz,
|
|
pGamzxx, pGamzxy, pGamzxz, pGamzyy, pGamzyz, pGamzzz,
|
|
pRxx, pRxy, pRxz, pRyy, pRyz, pRzz,
|
|
psi4RR, psi4II);
|
|
|
|
thetap = sqrt((2 * pl + 1.0) / 4.0 / PI) * misc::Wigner_d_function(pl, pm, spinw, costheta); // note the variation from -2 to 2
|
|
|
|
// find back the one
|
|
pchi = pchi + 1;
|
|
#ifdef GaussInt
|
|
// wtcostheta is even function respect costheta
|
|
RP_out[countlm] = RP_out[countlm] + thetap / pchi / pchi * (psi4RR * cosmphi + psi4II * sinmphi) * wtcostheta[i];
|
|
IP_out[countlm] = IP_out[countlm] + thetap / pchi / pchi * (psi4II * cosmphi - psi4RR * sinmphi) * wtcostheta[i];
|
|
#else
|
|
RP_out[countlm] = RP_out[countlm] + thetap / pchi / pchi * (psi4RR * cosmphi + psi4II * sinmphi);
|
|
IP_out[countlm] = IP_out[countlm] + thetap / pchi / pchi * (psi4II * cosmphi - psi4RR * sinmphi);
|
|
#endif
|
|
}
|
|
countlm++; // no sanity check for countlm and NN which should be noted in the input parameters
|
|
}
|
|
}
|
|
|
|
for (int ii = 0; ii < NN; ii++)
|
|
{
|
|
#ifdef GaussInt
|
|
RP_out[ii] = RP_out[ii] * rex * dphi;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi;
|
|
#else
|
|
RP_out[ii] = RP_out[ii] * rex * dphi * dcostheta;
|
|
IP_out[ii] = IP_out[ii] * rex * dphi * dcostheta;
|
|
#endif
|
|
}
|
|
//|------+ Communicate and sum the results from each processor.
|
|
|
|
{
|
|
double *RPIP_out = new double[2 * NN];
|
|
double *RPIP = new double[2 * NN];
|
|
memcpy(RPIP_out, RP_out, NN * sizeof(double));
|
|
memcpy(RPIP_out + NN, IP_out, NN * sizeof(double));
|
|
MPI_Allreduce(RPIP_out, RPIP, 2 * NN, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
|
memcpy(RP, RPIP, NN * sizeof(double));
|
|
memcpy(IP, RPIP + NN, NN * sizeof(double));
|
|
delete[] RPIP_out;
|
|
delete[] RPIP;
|
|
}
|
|
|
|
//|------= Free memory.
|
|
|
|
delete[] pox[0];
|
|
delete[] pox[1];
|
|
delete[] pox[2];
|
|
delete[] shellf;
|
|
delete[] RP_out;
|
|
delete[] IP_out;
|
|
DG_List->clearList();
|
|
}
|
|
//|----------------------------------------------------------------
|
|
// do not discriminate box and shell
|
|
//|----------------------------------------------------------------
|
|
bool surface_integral::SR_Interp_Points(MyList<var> *VarList, cgh *GH, ShellPatch *SH,
|
|
int NN, double **XX, double *Shellf)
|
|
{
|
|
MyList<var> *varl;
|
|
int num_var = 0;
|
|
varl = VarList;
|
|
while (varl)
|
|
{
|
|
num_var++;
|
|
varl = varl->next;
|
|
}
|
|
|
|
double pox[3];
|
|
for (int i = 0; i < NN; i++)
|
|
{
|
|
for (int j = 0; j < 3; j++)
|
|
pox[j] = XX[j][i];
|
|
int lev = GH->levels - 1;
|
|
bool notfound = true;
|
|
|
|
while (notfound)
|
|
{
|
|
if (lev < 0)
|
|
{
|
|
if (SH)
|
|
{
|
|
if (SH->Interp_One_Point(VarList, pox, Shellf + i * num_var, Symmetry))
|
|
{
|
|
return true;
|
|
}
|
|
if (myrank == 0)
|
|
cout << "surface_integral::SR_Interp_Points point (" << pox[0] << "," << pox[1] << "," << pox[2] << ") is out of cgh and shell domain!" << endl;
|
|
}
|
|
else
|
|
{
|
|
if (myrank == 0)
|
|
cout << "surface_integral::SR_Interp_Points: point (" << pox[0] << "," << pox[1] << "," << pox[2] << ") is out of cgh domain!" << endl;
|
|
}
|
|
return false;
|
|
}
|
|
MyList<Patch> *Pp = GH->PatL[lev];
|
|
while (Pp)
|
|
{
|
|
if (Pp->data->Interp_ONE_Point(VarList, pox, Shellf + i * num_var, Symmetry))
|
|
{
|
|
notfound = false;
|
|
break;
|
|
}
|
|
Pp = Pp->next;
|
|
}
|
|
lev--;
|
|
}
|
|
}
|
|
return true;
|
|
}
|