205 lines
7.0 KiB
C
205 lines
7.0 KiB
C
// c99 -o ../../tests/pwraytests/raypwtest1 -I .. ray_planewaves.c -lgsl -lm ../legendre.c ../vswf.c ../bessel.c -lblas
|
|
#include <gsl/gsl_rng.h>
|
|
#include <gsl/gsl_math.h>
|
|
#include <gsl/gsl_randist.h>
|
|
#include <assert.h>
|
|
#include "vswf.h"
|
|
#include "vectors.h"
|
|
#include "string.h"
|
|
#include "indexing.h"
|
|
|
|
char *normstr(qpms_normalisation_t norm) {
|
|
//int csphase = qpms_normalisation_t_csphase(norm);
|
|
norm = qpms_normalisation_t_normonly(norm);
|
|
switch (norm) {
|
|
case QPMS_NORMALISATION_NONE:
|
|
return "none";
|
|
case QPMS_NORMALISATION_SPHARM:
|
|
return "spharm";
|
|
case QPMS_NORMALISATION_POWER:
|
|
return "power";
|
|
default:
|
|
return "!!!undef!!!";
|
|
}
|
|
}
|
|
#define MIN(x,y) (((x)<(y))?(x):(y))
|
|
|
|
int main(int argc, char **argv) {
|
|
gsl_rng *rng = gsl_rng_alloc(gsl_rng_ranlxs0);
|
|
gsl_rng_set(rng, 666);
|
|
|
|
|
|
int nraysteps = 512;
|
|
|
|
|
|
// parametry: prefix, kx, ky, kz, E0x, E0y, E0z, norma, lmax
|
|
// defaults
|
|
double kx = 1, ky = 0, kz = 0, E0x = 0, E0y = 0, E0z = 1;
|
|
qpms_l_t lMax = 10;
|
|
qpms_normalisation_t norm = QPMS_NORMALISATION_NONE_CS;
|
|
|
|
switch(MIN(argc, 10)) {
|
|
case 10: lMax = atoi(argv[9]);
|
|
case 9: norm = atoi(argv[8]);
|
|
case 8: E0z = strtod(argv[7], NULL);
|
|
case 7: E0y = strtod(argv[6], NULL);
|
|
case 6: E0x = strtod(argv[5], NULL);
|
|
case 5: kz = strtod(argv[4], NULL);
|
|
case 4: ky = strtod(argv[3], NULL);
|
|
case 3: kx = strtod(argv[2], NULL);
|
|
case 2: break;
|
|
case 1: fputs("At least one argument needed (filename prefix)\n", stderr);
|
|
}
|
|
|
|
qpms_y_t nelem = qpms_lMax2nelem(lMax);
|
|
int nrays = 10;
|
|
double sigma = 4;
|
|
cart3_t rays[nrays];
|
|
double relerrs[nrays];
|
|
memset(rays, 0, nrays * sizeof(cart3_t));
|
|
rays[0].x = rays[1].y = rays[2].z = sigma;
|
|
double relerrthreshold = 1e-11;
|
|
for (unsigned i = 3; i < nrays; ++i) {
|
|
cart3_t *w = rays+i;
|
|
w->x = gsl_ran_gaussian(rng, sigma);
|
|
w->y = gsl_ran_gaussian(rng, sigma);
|
|
w->z = gsl_ran_gaussian(rng, sigma);
|
|
}
|
|
|
|
|
|
|
|
cart3_t k = {kx, ky, kz};
|
|
k = cart3_scale(1./cart3norm(k),k); // automatically normalise
|
|
|
|
ccart3_t E0 = {E0x, E0y, E0z};
|
|
sph_t ks = cart2sph(k);
|
|
csphvec_t E0s = ccart2csphvec(E0, ks);
|
|
complex double Lc[nelem], Mc[nelem], Nc[nelem];
|
|
if (qpms_planewave2vswf_fill_sph(ks, E0s, Lc, Mc, Nc, lMax, norm)) abort();
|
|
|
|
|
|
// each ray will have its file
|
|
FILE *rfile[nrays];
|
|
{
|
|
char fname[strlen(argv[1])+20];
|
|
for (int p = 0; p < nrays; ++p) {
|
|
sprintf(fname, "%s.%d", argv[1], p);
|
|
rfile[p] = fopen(fname, "w");
|
|
fputs("##\tnorm\tlMax\tnelem\n", rfile[p]);
|
|
fprintf(rfile[p], "#\t%d\t%d\t%d\n",
|
|
(int)norm, (int)lMax, (int)nelem);
|
|
fputs("##\tkx\tky\tkz\tR(E0x)\tI(E0x)\tR(E0y)\tI(E0y)\tR(E0z)\tI(E0z)\n", rfile[p]);
|
|
fprintf(rfile[p], "#\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\n",
|
|
k.x, k.y, k.z,
|
|
creal(E0.x), cimag(E0.x),
|
|
creal(E0.y), cimag(E0.y),
|
|
creal(E0.z), cimag(E0.z)
|
|
);
|
|
sph_t ks = cart2sph(k);
|
|
csphvec_t E0s = ccart2csphvec(E0, ks);
|
|
fputs("##\tkr\tkθ\tkφ\tR(E0r)\tI(E0r)\tR(E0θ)\tI(E0θ)\tR(E0φ)\tI(E0φ)\n", rfile[p]);
|
|
fprintf(rfile[p], "#\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\n",
|
|
ks.r, ks.theta, ks.phi,
|
|
creal(E0s.rc), cimag(E0s.rc),
|
|
creal(E0s.thetac), cimag(E0s.thetac),
|
|
creal(E0s.phic), cimag(E0s.phic)
|
|
);
|
|
fprintf(rfile[p], "#\tThis ray cart:\t%g\t%g\t%g\n",
|
|
rays[p].x, rays[p].y, rays[p].z);
|
|
sph_t ps = cart2sph(rays[p]);
|
|
fprintf(rfile[p], "#\tThis ray sph:\t%g\t%g\t%g\n",
|
|
ps.r, ps.theta, ps.phi);
|
|
fputs("## TODO Coefficients of the wave decomposition\n", rfile[p]); // TODO print Lc, Mc, Nc
|
|
fputs("\t"
|
|
"\t\t\t\t\t\t" "\t"
|
|
"\t\t\t\t\t\t"
|
|
"\t\t\t\t\t\t"
|
|
"\t\t\t\t\t\t" "\t\t\t\t\t\t", rfile[p]);
|
|
for(qpms_y_t y = 0; y < nelem; ++y){ // TODO print also the longitudinal waves?
|
|
for(int i = 0; i < 3; ++i)
|
|
fprintf(rfile[p], "%g\t%g\t", creal(Mc[y]), cimag(Mc[y]));
|
|
for(int i = 0; i < 3; ++i)
|
|
fprintf(rfile[p], "%g\t%g\t", creal(Nc[y]), cimag(Nc[y]));
|
|
}
|
|
fputc('\n', rfile[p]);
|
|
|
|
fputs("#step\t"
|
|
"x\ty\tz\tr\tθ\tφ\tphase\t"
|
|
"R(Ex)\tI(Ex)\tR(Ey)\tI(Ey)\tR(Ez)\tI(Ez)\t"
|
|
"R(Er)\tI(Er)\tR(Eθ)\tI(Eθ)\tR(Eφ)\tI(Eφ)\t"
|
|
"R(rEx)\tI(rEx)\tR(rEy)\tI(rEy)\tR(rEz)\tI(rEz)\t"
|
|
"R(rEr)\tI(rEr)\tR(rEθ)\tI(rEθ)\tR(rEφ)\tI(rEφ)\t",
|
|
rfile[p]
|
|
);
|
|
|
|
|
|
for(qpms_y_t y = 0; y < nelem; ++y) {
|
|
qpms_l_t l2; qpms_m_t m2;
|
|
qpms_y2mn_p(y, &m2, &l2);
|
|
fprintf(rfile[p], // TODO print also the longitudinal waves?
|
|
"R(M2(%d,%d).r)\tI(M2(%d,%d).r)\t"
|
|
"R(M2(%d,%d).θ)\tI(M2(%d,%d).θ)\t"
|
|
"R(M2(%d,%d).φ)\tI(M2(%d,%d).φ)\t"
|
|
"R(N2(%d,%d).r)\tI(N2(%d,%d).r)\t"
|
|
"R(N2(%d,%d).θ)\tI(N2(%d,%d).θ)\t"
|
|
"R(N2(%d,%d).φ)\tI(N2(%d,%d).φ)\t",
|
|
l2,m2,l2,m2, l2,m2,l2,m2, l2,m2,l2,m2,
|
|
l2,m2,l2,m2, l2,m2,l2,m2, l2,m2,l2,m2
|
|
);
|
|
}
|
|
fputc('\n', rfile[p]);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for (int step = 0; step <= nraysteps; ++step) {
|
|
double stepratio = (double) step / (double) nraysteps;
|
|
for(int p = 0; p < nrays; ++p) {
|
|
cart3_t cart = cart3_scale(stepratio, rays[p]);
|
|
sph_t sph = cart2sph(cart);
|
|
double phase = cart3_dot(k, cart);
|
|
ccart3_t E = ccart3_scale(cexp(I*phase), E0);
|
|
csphvec_t L[nelem], M[nelem], N[nelem], Es, rEs;
|
|
Es = ccart2csphvec(E, sph);
|
|
rEs = qpms_eval_vswf(sph, Lc, Mc, Nc, lMax, QPMS_BESSEL_REGULAR, norm); // TODO maybe also check this by summing manually Lc * L etc.
|
|
ccart3_t rEc = csphvec2ccart(rEs, sph);
|
|
if (qpms_vswf_fill(L, M, N, lMax, sph, QPMS_BESSEL_REGULAR, norm)) abort();
|
|
|
|
fprintf(rfile[p],"%d\t"
|
|
"%g\t%g\t%g\t%g\t%g\t%g\t" "%g\t"
|
|
"%g\t%g\t%g\t%g\t%g\t%g\t"
|
|
"%g\t%g\t%g\t%g\t%g\t%g\t"
|
|
"%g\t%g\t%g\t%g\t%g\t%g\t"
|
|
"%g\t%g\t%g\t%g\t%g\t%g\t",
|
|
step, cart.x, cart.y, cart.z, sph.r, sph.theta, sph.phi, phase,
|
|
creal(E.x), cimag(E.x), creal(E.y), cimag(E.y), creal(E.z), cimag(E.z),
|
|
creal(Es.rc), cimag(Es.rc), creal(Es.thetac), cimag(Es.thetac), creal(Es.phic), cimag(Es.phic),
|
|
creal(rEc.x), cimag(rEc.x), creal(rEc.y), cimag(rEc.y), creal(rEc.z), cimag(rEc.z),
|
|
creal(rEs.rc), cimag(rEs.rc), creal(rEs.thetac), cimag(rEs.thetac), creal(rEs.phic), cimag(rEs.phic)
|
|
);
|
|
|
|
for(qpms_y_t y = 0; y < nelem; ++y) {
|
|
csphvec_t /*Lsc,*/ Msc, Nsc; // TODO print also the longitudinal waves?
|
|
//Lsc = csphvec_scale(Lc[y], L);
|
|
Msc = M[y];//csphvec_scale(Mc[y], M[y]);
|
|
Nsc = N[y];//csphvec_scale(Nc[y], N[y]);
|
|
fprintf(rfile[p], "%g\t%g\t%g\t%g\t%g\t%g\t""%g\t%g\t%g\t%g\t%g\t%g\t",
|
|
creal(Msc.rc), cimag(Msc.rc),
|
|
creal(Msc.thetac), cimag(Msc.thetac),
|
|
creal(Msc.phic), cimag(Msc.phic),
|
|
creal(Nsc.rc), cimag(Nsc.rc),
|
|
creal(Nsc.thetac), cimag(Nsc.thetac),
|
|
creal(Nsc.phic), cimag(Nsc.phic)
|
|
);
|
|
}
|
|
fputc('\n', rfile[p]);
|
|
}
|
|
}
|
|
|
|
for (int p = 0; p < nrays; ++p)
|
|
fclose(rfile[p]);
|
|
gsl_rng_free(rng);
|
|
}
|
|
|