NFFT Logo 3.0.2 API Reference
Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals

fields_fastsum.c

Go to the documentation of this file.
00001 
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include <complex.h>
00012 #include <math.h>
00013 
00014 #include "fastsum.h"
00015 #include "fields_fastsum.h"
00016 #include "kernels.h"
00017 
00019 void fields_fastsum_init(fields_fastsum_plan *plan, int N_total, unsigned flags, int nn, int m, int p, double eps_I, double eps_B) {
00020   double *kernel_param;
00021 
00022   kernel_param = (double *)malloc(sizeof(double));
00023   kernel_param[0] = 0.0;
00024   plan->N_total = N_total;
00025   plan->q = (double *)malloc(N_total*(sizeof(double)));
00026   plan->r = (double *)malloc(3*N_total*(sizeof(double)));
00027   plan->E = (double *)malloc(3*N_total*(sizeof(double)));
00028 
00029   fastsum_init_guru(&plan->fsum, 3, N_total, N_total, one_over_cube, kernel_param, flags, nn, m, p, eps_I, eps_B);
00030 }
00031 
00033 void fields_fastsum_finalize(fields_fastsum_plan *plan) {
00034   free(plan->fsum.kernel_param);
00035   fastsum_finalize(&plan->fsum);
00036 
00037   free(plan->E);
00038   free(plan->r);
00039   free(plan->q);
00040 }
00041 
00043 void fields_fastsum_exact(fields_fastsum_plan *plan) {
00044   int j;
00045   int l;
00046   double s;
00047   double E_pre = 1 / (4*PI*EPSILON_0);
00048   double diff[3];
00049   double sum[3];
00050 
00051   for(j = 0; j < plan->N_total; j++) {
00052     sum[0] = 0.0;
00053     sum[1] = 0.0;
00054     sum[2] = 0.0;
00055     for(l = 0; l < plan->N_total; l++) {
00056       if (j == l) {
00057         continue;
00058       }
00059       diff[0] = plan->r[j*3] - plan->r[l*3];
00060       diff[1] = plan->r[j*3+1] - plan->r[l*3+1];
00061       diff[2] = plan->r[j*3+2] - plan->r[l*3+2];
00062       s = diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2];
00063       s = plan->q[l] / sqrt(s*s*s);
00064       sum[0] += s * diff[0];
00065       sum[1] += s * diff[1];
00066       sum[2] += s * diff[2];
00067     }
00068     plan->E[j*3] = E_pre * sum[0];
00069     plan->E[j*3+1] = E_pre * sum[1];
00070     plan->E[j*3+2] = E_pre * sum[2];
00071   }
00072 }
00073 
00075 void fields_fastsum_simple(fields_fastsum_plan *plan) {
00076   int k;
00077   int t;
00078   int j;
00079   int l;
00080   double E_pre = 1 / (4*PI*EPSILON_0);
00081 
00082   for(k = 0; k < plan->N_total; k++) {
00083     for(t = 0; t < 3; t++) {
00084       plan->fsum.x[k*3+t] = plan->r[k*3+t];
00085       plan->fsum.y[k*3+t] = plan->r[k*3+t];
00086     }
00087     plan->fsum.alpha[k] = plan->q[k];
00088   }
00089 
00090   /* steps 1, 2, 3, 6, 7 */
00091   fastsum_precompute(&plan->fsum);
00092   fastsum_trafo(&plan->fsum);
00093   for(j = 0; j < plan->N_total; j++) {
00094     for(t = 0; t < 3; t++) {
00095       plan->E[j*3+t] = plan->r[j*3+t] * creal(plan->fsum.f[j]);
00096     }
00097   }
00098 
00099   for(t = 0; t < 3; t++) {
00100     for(k = 0; k < plan->N_total; k++) {
00101       for(l = 0; l < 3; l++) {
00102         plan->fsum.x[k*3+l] = plan->r[k*3+l];
00103         plan->fsum.y[k*3+l] = plan->r[k*3+l];
00104       }
00105     }
00106     for(l = 0; l < plan->N_total; l++) {
00107       plan->fsum.alpha[l] = plan->q[l] * plan->r[l*3+t];
00108     }
00109 
00110     /* steps 1, 4, 5, 6, 7 */
00111     fastsum_precompute(&plan->fsum);
00112     fastsum_trafo(&plan->fsum);
00113     for(j = 0; j < plan->N_total; j++) {
00114       plan->E[j*3+t] -= creal(plan->fsum.f[j]);
00115       plan->E[j*3+t] *= E_pre;
00116     }
00117   }
00118 }
00119 
00121 void FieldsSearchTree(double *result, int t, double *x, complex *alpha, double *xmin, double *xmax, int N, complex (*kernel)(double , int , const double *), const double *param, int Ad, double *Add, int p, unsigned flags)
00122 {
00123   int m=N/2;
00124   double Min=xmin[t], Max=xmax[t], Median=x[m*3+t];
00125   double a=fabs(Max-Min)/2;
00126   double r;
00127   double kernel_value;
00128   double q;
00129 
00130   if (N==0)
00131     return;
00132 
00133   if (Min>Median)
00134     FieldsSearchTree(result, (t+1)%3,x+(m+1)*3,alpha+(m+1),xmin,xmax,N-m-1,kernel,param,Ad,Add,p,flags);
00135   else if (Max<Median)
00136     FieldsSearchTree(result, (t+1)%3,x,alpha,xmin,xmax,m,kernel,param,Ad,Add,p,flags);
00137   else
00138   {
00139     if (x[m*3]>xmin[0] && x[m*3]<xmax[0] && x[m*3+1]>xmin[1] && x[m*3+1]<xmax[1] && x[m*3+2]>xmin[2] && x[m*3+2]<xmax[2])
00140     {
00141       r = (xmin[0]+a-x[m*3])*(xmin[0]+a-x[m*3]) + (xmin[1]+a-x[m*3+1])*(xmin[1]+a-x[m*3+1]) + (xmin[2]+a-x[m*3+2])*(xmin[2]+a-x[m*3+2]);
00142         /* remember: xmin+a = y */
00143       r=sqrt(r);
00144       if (fabs(r)<a)
00145       {
00146         kernel_value = kernel(r,0,param);
00147         if (flags & EXACT_NEARFIELD)
00148           kernel_value -= regkern(kernel,r,p,param,a,1.0/16.0);      /* exact value  */
00149         else
00150           kernel_value -= kubintkern(r,Add,Ad,a);                    /* spline approximation */
00151 
00152         q = creal(alpha[m]);
00153 
00154         result[0] += (xmin[0]+a-x[m*3])*q*kernel_value;              /* alpha*(kern-regkern) */
00155         result[1] += (xmin[1]+a-x[m*3+1])*q*kernel_value;
00156         result[2] += (xmin[2]+a-x[m*3+2])*q*kernel_value;
00157       }
00158     }
00159     FieldsSearchTree(result,(t+1)%3,x+(m+1)*3,alpha+(m+1),xmin,xmax,N-m-1,kernel,param,Ad,Add,p,flags);
00160     FieldsSearchTree(result,(t+1)%3,x,alpha,xmin,xmax,m,kernel,param,Ad,Add,p,flags);
00161   }
00162 }
00163 
00165 void fields_fastsum_precompute(fields_fastsum_plan *plan) {
00166   int k;
00167   int t;
00168   double time;
00169 
00170   time=nfft_second();
00171 
00172   for(k = 0; k < plan->N_total; k++) {
00173     for(t = 0; t < 3; t++) {
00174       plan->fsum.x[k*3+t] = plan->r[k*3+t];
00175       plan->fsum.y[k*3+t] = plan->r[k*3+t];
00176     }
00177     plan->fsum.alpha[k] = plan->q[k];
00178   }
00179 
00180   fastsum_precompute(&plan->fsum);
00181 }
00182 
00183 
00185 void fields_fastsum_trafo(fields_fastsum_plan *plan) {
00186   int j,k,t;
00187   double E_pre = 1 / (4*PI*EPSILON_0);
00188 
00190   double ymin[3], ymax[3];
00191 
00193   nfft_adjoint(&(plan->fsum.mv1));
00194 
00196   for (k=0; k<plan->fsum.mv2.N_total; k++)
00197     plan->fsum.mv2.f_hat[k] = plan->fsum.b[k] * plan->fsum.mv1.f_hat[k];
00198 
00200   nfft_trafo(&(plan->fsum.mv2));
00201   for(j = 0; j < plan->N_total; j++) {
00202     plan->E[j*3] = plan->r[j*3] * creal(plan->fsum.mv2.f[j]);
00203     plan->E[j*3+1] = plan->r[j*3+1] * creal(plan->fsum.mv2.f[j]);
00204     plan->E[j*3+2] = plan->r[j*3+2] * creal(plan->fsum.mv2.f[j]);
00205   }
00206 
00207   for(t = 0; t < 3; t++) {
00209     for(k = 0; k < plan->N_total; k++)
00210       plan->fsum.mv1.f[k] = plan->fsum.alpha[k] * plan->fsum.x[3*k+t];
00211     nfft_adjoint(&(plan->fsum.mv1));
00212 
00214     for (k=0; k<plan->fsum.mv2.N_total; k++)
00215       plan->fsum.mv2.f_hat[k] = plan->fsum.b[k] * plan->fsum.mv1.f_hat[k];
00216 
00218     nfft_trafo(&(plan->fsum.mv2));
00219     for(j = 0; j < plan->N_total; j++)
00220       plan->E[j*3+t] -= creal(plan->fsum.mv2.f[j]);
00221   }
00222 
00224   for (j=0; j<plan->fsum.M_total; j++)
00225   {
00226     ymin[0] = plan->fsum.y[3*j] - plan->fsum.eps_I;
00227     ymax[0] = plan->fsum.y[3*j] + plan->fsum.eps_I;
00228     ymin[1] = plan->fsum.y[3*j+1] - plan->fsum.eps_I;
00229     ymax[1] = plan->fsum.y[3*j+1] + plan->fsum.eps_I;
00230     ymin[2] = plan->fsum.y[3*j+2] - plan->fsum.eps_I;
00231     ymax[2] = plan->fsum.y[3*j+2] + plan->fsum.eps_I;
00232 
00233     FieldsSearchTree(plan->E+3*j, 0, plan->fsum.x, plan->fsum.alpha, ymin, ymax, plan->fsum.N_total, plan->fsum.kernel, plan->fsum.kernel_param, plan->fsum.Ad, plan->fsum.Add, plan->fsum.p, plan->fsum.flags);
00234 
00235     plan->E[j*3] *= E_pre;
00236     plan->E[j*3+1] *= E_pre;
00237     plan->E[j*3+2] *= E_pre;
00238   }
00239 }
00240 

Generated on 22 Jan 2007 by Doxygen 1.4.1