Files
AMSS-NCKU/AMSS_NCKU_source/surface_integral.C
CGH0S7 d06d5b4db8 Add targeted point-to-point Interp_Points overload for surface_integral
Instead of broadcasting all interpolated point data to every MPI rank,
the new overload sends each point only to the one rank that needs it
for integration, reducing communication volume by ~nprocs times.

The consumer rank is computed deterministically using the same Nmin/Nmax
work distribution formula used by surface_integral callers. Two active
call sites (surf_Wave and surf_MassPAng with MPI_COMM_WORLD) now use
the new overload. Other callers (ShellPatch, Comm_here variants, etc.)
remain unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-10 19:18:56 +08:00

3752 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;
}