00001 #ifndef __INCLUDE_CHARRAY_CC
00002 #define __INCLUDE_CHARRAY_CC
00003 #include "arrays.h"
00004 using namespace std;
00005
00006 CRandom *CCHArray::randy=NULL;
00007 CCHCalc *CCHArray::chcalc=NULL;
00008
00009 CCHArray::CCHArray(int LMAXset,int NRADIALset,double RADSTEPset){
00010 if(chcalc==NULL) chcalc=new CCHCalc();
00011 NRADIAL=NRADIALset;
00012 LMAX=LMAXset;
00013 RADSTEP=RADSTEPset;
00014 XSYM=YSYM=ZSYM=false;
00015 dlx=dly=dlz=1;
00016 CreateArray();
00017 }
00018
00019 CCHArray::CCHArray(int LMAXset,int NRADIALset,double RADSTEPset,bool XSYMset,bool YSYMset,bool ZSYMset){
00020 if(chcalc==NULL) chcalc=new CCHCalc();
00021 NRADIAL=NRADIALset;
00022 RADSTEP=RADSTEPset;
00023 LMAX=LMAXset;
00024 XSYM=XSYMset;
00025 YSYM=YSYMset;
00026 ZSYM=ZSYMset;
00027 dlx=dly=dlz=1;
00028 if(XSYM) dlx=2;
00029 if(YSYM) dly=2;
00030 if(ZSYM) dlz=2;
00031 CreateArray();
00032 }
00033
00034 CCHArray::CCHArray(string arrayparsfilename){
00035 dlx=dly=dlz=1;
00036 if(chcalc==NULL) chcalc=new CCHCalc();
00037 parameterMap apars;
00038
00039 parameter::ReadParsFromFile(apars,arrayparsfilename);
00040 if(parameter::getB(apars,"IDENTICAL",false)){
00041 parameter::set(apars,"XSYM",true);
00042 parameter::set(apars,"YSYM",true);
00043 parameter::set(apars,"ZSYM",true);
00044 }
00045
00046 NRADIAL=parameter::getI(apars,"NRADIAL",-999);
00047 LMAX=parameter::getI(apars,"LMAX",-999);
00048 RADSTEP=parameter::getD(apars,"RADSTEP",-999);
00049 XSYM=parameter::getB(apars,"XSYM",false);
00050 YSYM=parameter::getB(apars,"YSYM",false);
00051 ZSYM=parameter::getB(apars,"ZSYM",false);
00052 if(XSYM) dlx=2;
00053 if(YSYM) dly=2;
00054 if(ZSYM) dlz=2;
00055 PrintPars();
00056
00057 CreateArray();
00058 }
00059
00060 void CCHArray::CreateArray(){
00061 int lx,ly,lz,ir;
00062
00063 A=new double ***[LMAX+1];
00064 for(lx=0;lx<=LMAX;lx+=dlx){
00065 A[lx]=new double **[LMAX+1-lx];
00066 for(ly=0;ly<=LMAX-lx;ly+=dly){
00067 A[lx][ly]=new double *[LMAX+1-lx-ly];
00068 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00069 A[lx][ly][lz]=new double[NRADIAL];
00070 for(ir=0;ir<NRADIAL;ir++) A[lx][ly][lz][ir]=0.0;
00071 }
00072 }
00073 }
00074
00075 }
00076
00077 CCHArray::~CCHArray(){
00078 int lx,ly,lz;
00079 for(lx=0;lx<=LMAX;lx+=dlx){
00080 for(ly=0;ly<=LMAX-lx;ly+=dly){
00081 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz) delete [] A[lx][ly][lz];
00082 delete [] A[lx][ly];
00083 }
00084 delete [] A[lx];
00085 }
00086 delete A;
00087 }
00088
00089 int CCHArray::GetLMAX(){
00090 return LMAX;
00091 }
00092
00093 void CCHArray::SetLMAX(int LMAXset){
00094 if(LMAXset<LMAX) LMAX=LMAXset;
00095 }
00096
00097 int CCHArray::GetNRADIAL(){
00098 return NRADIAL;
00099 }
00100
00101 double CCHArray::GetRADSTEP(){
00102 return RADSTEP;
00103 }
00104
00105 void CCHArray::SetRADSTEP(double RADSTEPset){
00106 RADSTEP=RADSTEPset;
00107 }
00108
00109 double CCHArray::GetElement(int lx,int ly,int lz,int ir){
00110 int L=lx+ly+lz;
00111 if(L<=LMAX && lx%dlx==0 && ly%dly==0 && lz%dlz==0 && ir<NRADIAL)
00112 return A[lx][ly][lz][ir];
00113 else{
00114 printf("WARNING: Tried to get non-existent element in CCHArray\n");
00115 printf("LMAX=%d, XSYM=%d, YSYM=%d, ZSYM=%d, ir=%d\n",
00116 LMAX,int(XSYM),int(YSYM),int(ZSYM),ir);
00117 printf("l=(%d,%d,%d), ir=%d\n",lx,ly,lz,ir);
00118 return 0.0;
00119 }
00120 }
00121
00122 double CCHArray::GetElement(int lx,int ly,int lz,double r){
00123 int ir=int(floor(r/RADSTEP));
00124 return GetElement(lx,ly,lz,ir);
00125 }
00126
00127 void CCHArray::SetElement(int lx,int ly,int lz,int ir,double Element){
00128 int L=lx+ly+lz;
00129 if(L<=LMAX && L>=0 && lx%dlx==0 && ly%dly==0 && lz%dlz==0 && ir<NRADIAL)
00130 A[lx][ly][lz][ir]=Element;
00131 else{
00132 printf("Tried to set element out of bounds in CCHArray\n");
00133 printf("LMAX=%d, XSYM=%d, YSYM=%d, ZSYM=%d, ir=%d\n",
00134 LMAX,int(XSYM),int(YSYM),int(ZSYM),ir);
00135 printf("l=(%d,%d,%d), ir=%d\n",lx,ly,lz,ir);
00136 exit(1);
00137
00138 }
00139 }
00140
00141 void CCHArray::SetElement(int lx,int ly,int lz,double r,double Element){
00142 int ir=int(floor(r/RADSTEP));
00143 SetElement(lx,ly,lz,ir,Element);
00144 }
00145
00146 void CCHArray::IncrementElement(int lx,int ly,int lz,int ir,double increment){
00147 int L=lx+ly+lz;
00148 if(L<=LMAX && L>=0 && lx%dlx==0 && ly%dly==0 && lz%dlz==0 && ir<NRADIAL) {
00149 A[lx][ly][lz][ir]+=increment;
00150 }
00151 else{
00152 printf("OUT OF BOUNDS IN INCREMENTELEMENT\n");
00153 printf("ell=(%d,%d,%d), ir=%d\n",lx,ly,lz,ir);
00154 exit(1);
00155 }
00156
00157 }
00158
00159 void CCHArray::IncrementElement(int lx,int ly,int lz,double r,double increment){
00160 int ir=int(floor(r/RADSTEP));
00161 IncrementElement(lx,ly,lz,ir,increment);
00162 }
00163
00164 void CCHArray::ScaleArray(double scalefactor){
00165 int lx,ly,lz,ir;
00166 for(lx=0;lx<=LMAX;lx+=dlx){
00167 for(ly=0;ly<=LMAX-lx;ly+=dly){
00168 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00169 for(ir=0;ir<NRADIAL;ir++) A[lx][ly][lz][ir]*=scalefactor;
00170 }
00171 }
00172 }
00173 }
00174
00175 void CCHArray::ScaleArray(double scalefactor, int ir){
00176 int lx,ly,lz;
00177 for(lx=0;lx<=LMAX;lx+=dlx){
00178 for(ly=0;ly<=LMAX-lx;ly+=dly){
00179 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00180 A[lx][ly][lz][ir]*=scalefactor;
00181 }
00182 }
00183 }
00184 }
00185
00186 void CCHArray::ZeroArray_Partial(int LMAX_partial){
00187 int lx,ly,lz,ir;
00188 for(lx=0;lx<=LMAX_partial;lx+=dlx){
00189 for(ly=0;ly<=LMAX_partial-lx;ly+=dly){
00190 for(lz=0;lz<=LMAX_partial-lx-ly;lz+=dlz){
00191 for(ir=0;ir<NRADIAL;ir++) A[lx][ly][lz][ir]=0.0;
00192 }
00193 }
00194 }
00195 }
00196
00197 void CCHArray::ZeroArray_Partial(int LMAX_partial,int ir){
00198 int lx,ly,lz;
00199 for(lx=0;lx<=LMAX_partial;lx+=dlx){
00200 for(ly=0;ly<=LMAX_partial-lx;ly+=dly){
00201 for(lz=0;lz<=LMAX_partial-lx-ly;lz+=dlz){
00202 A[lx][ly][lz][ir]=0.0;
00203 }
00204 }
00205 }
00206 }
00207
00208 void CCHArray::ZeroArray(){
00209 int lx,ly,lz,ir;
00210 for(lx=0;lx<=LMAX;lx+=dlx){
00211 for(ly=0;ly<=LMAX-lx;ly+=dly){
00212 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00213 for(ir=0;ir<NRADIAL;ir++) A[lx][ly][lz][ir]=0.0;
00214 }
00215 }
00216 }
00217 }
00218
00219 void CCHArray::ZeroArray(int lx,int ly,int lz){
00220 int ir;
00221 for(ir=0;ir<NRADIAL;ir++) A[lx][ly][lz][ir]=0.0;
00222 }
00223
00224 void CCHArray::ZeroArray(int ir){
00225 int lx,ly,lz;
00226 for(lx=0;lx<=LMAX;lx+=dlx){
00227 for(ly=0;ly<=LMAX-lx;ly+=dly){
00228 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz)
00229 A[lx][ly][lz][ir]=0.0;
00230 }
00231 }
00232 }
00233
00234 void CCHArray::Print(int lx,int ly,int lz){
00235 for(int ir=0;ir<NRADIAL;ir++){
00236 printf("%6.3f: %10.3e\n",(0.5+ir)*RADSTEP,A[lx][ly][lz][ir]);
00237 }
00238 }
00239
00240 void CCHArray::PrintProjections(){
00241 int lx,ly,lz;
00242 double a0,ax,ay,az;
00243 printf("_____ lx=ly=lz=0 x-proj y-proj z-proj _____\n");
00244 for(int ir=0;ir<NRADIAL;ir++){
00245 a0=A[0][0][0][ir];
00246 ax=ay=az=0.0;
00247 ly=lz=0;
00248 for(lx=0;lx<=LMAX;lx+=dlx) ax+=A[lx][ly][lz][ir];
00249 lx=lz=0;
00250 for(ly=0;ly<=LMAX;ly+=dly) ay+=A[lx][ly][lz][ir];
00251 ly=lz=0;
00252 for(lz=0;lz<=LMAX;lz+=dlz) az+=A[lx][ly][lz][ir];
00253 printf("%7.3f: %10.3e %10.3e %10.3e %10.3e\n",(ir+0.5)*RADSTEP,a0,ax,ay,az);
00254 }
00255 }
00256
00257 void CCHArray::GetProjections(double **B){
00258 int lx,ly,lz;
00259 double a0,ax,ay,az;
00260 printf("_____ lx=ly=lz=0 x-proj y-proj z-proj _____\n");
00261 for(int ir=0;ir<NRADIAL;ir++){
00262 ax=ay=az=0.0;
00263 ly=lz=0;
00264 a0=A[0][0][0][ir];
00265 for(lx=0;lx<=LMAX;lx+=dlx) ax+=A[lx][ly][lz][ir];
00266 lx=lz=0;
00267 for(ly=0;ly<=LMAX;ly+=dly) ay+=A[lx][ly][lz][ir];
00268 ly=lz=0;
00269 for(lz=0;lz<=LMAX;lz+=dlz) az+=A[lx][ly][lz][ir];
00270 B[0][ir]=a0; B[1][ir]=ax; B[2][ir]=ay; B[3][ir]=az;
00271
00272 }
00273 }
00274
00275 void CCHArray::PrintArrayFixedIR(int ir){
00276 PrintArrayFixedIR(LMAX,ir);
00277 }
00278
00279 void CCHArray::PrintArrayFixedIR(int LMAXPrint,int ir){
00280 int L,lx,ly,lz,dL=1;
00281 if(XSYM && YSYM && ZSYM) dL=2;
00282 if(LMAXPrint>LMAX) LMAXPrint=LMAX;
00283
00284 printf("\n______________________________________________________\n");
00285 for(L=0;L<=LMAXPrint;L+=dL){
00286 printf(" L=%d\n",L);
00287 printf(" lx\\ly:");
00288 for(ly=0;ly<=L;ly+=dly) printf(" %4d ",ly);
00289 printf("\n");
00290
00291 for(lx=0;lx<=L;lx+=dlx){
00292 printf(" %3d ",lx);
00293 for(ly=0;ly<=L-lx;ly+=dly){
00294 lz=L-lx-ly;
00295 if(ZSYM==0 || lz%2==0)
00296 printf(" %10.3e ",A[lx][ly][lz][ir]);
00297 else printf("%10.3e ",0.0);
00298 }
00299 printf("\n");
00300 }
00301 printf("_________________________________________\n");
00302 }
00303 }
00304
00305 double CCHArray::GetBiggest(int ir){
00306 int lx,ly,lz;
00307 double biggy=0.0;
00308 for(lx=0;lx<=LMAX;lx+=dlx){
00309 for(ly=0;ly<=LMAX-lx;ly+=dly){
00310 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00311 if(fabs(A[lx][ly][lz][ir])>fabs(biggy))
00312 biggy=fabs(A[lx][ly][lz][ir]);
00313 }
00314 }
00315 }
00316 return biggy;
00317 }
00318
00319 bool CCHArray::GetXSYM(){
00320 if(XSYM) return true;
00321 else return false;
00322 }
00323
00324 bool CCHArray::GetYSYM(){
00325 if(YSYM) return true;
00326 else return false;
00327 }
00328
00329 bool CCHArray::GetZSYM(){
00330 if(ZSYM) return true;
00331 else return false;
00332 }
00333
00334 void CCHArray::WriteAX(string dirname){
00335 char filename[160],shellcommand[200];
00336 int ir,lx,ly,lz;
00337 FILE *fptr;
00338
00339 sprintf(shellcommand,"mkdir -p %s",dirname.c_str());
00340 system(shellcommand);
00341
00342 for(lx=0;lx<=1;lx+=dlx){
00343 for(ly=0;ly<=LMAX-lx;ly+=dly){
00344 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00345 sprintf(filename,"%s/lx%d_ly%d_lz%d.tmp",dirname.c_str(),lx,ly,lz);
00346 fptr=fopen(filename,"w");
00347 fprintf(fptr,"%d %g\n",NRADIAL,RADSTEP);
00348 for(ir=0;ir<NRADIAL;ir++){
00349 fprintf(fptr,"%g\n",A[lx][ly][lz][ir]);
00350 }
00351 fclose(fptr);
00352 }
00353 }
00354 }
00355 }
00356
00357 void CCHArray::WriteAllA(string dirname){
00358 char filename[160],shellcommand[200];
00359 int ir,lx,ly,lz;
00360 FILE *fptr;
00361
00362 sprintf(shellcommand,"mkdir -p %s",dirname.c_str());
00363 system(shellcommand);
00364
00365 for(lx=0;lx<=LMAX;lx+=dlx){
00366 for(ly=0;ly<=LMAX-lx;ly+=dly){
00367 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00368 sprintf(filename,"%s/lx%d_ly%d_lz%d.tmp",dirname.c_str(),lx,ly,lz);
00369 fptr=fopen(filename,"w");
00370 fprintf(fptr,"%d %g\n",NRADIAL,RADSTEP);
00371 for(ir=0;ir<NRADIAL;ir++){
00372 fprintf(fptr,"%16.10e\n",A[lx][ly][lz][ir]);
00373 }
00374 fclose(fptr);
00375 }
00376 }
00377 }
00378 }
00379
00380 void CCHArray::ReadAX(string dirname){
00381 char filename[120],shellcommand[240];
00382 int ir,lx,ly,lz,NRADIALread;
00383 double aa,RADSTEPread;
00384 FILE *fptr;
00385 for(lx=0;lx<=1;lx+=dlx){
00386 for(ly=0;ly<=LMAX-lx;ly+=dly){
00387 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00388 sprintf(filename,"%s/lx%d_ly%d_lz%d.tmp",dirname.c_str(),lx,ly,lz);
00389
00390 sprintf(shellcommand,
00391 "if [ ! -e %s ]; then echo Reading Error: %s, does not exist; fi",filename,filename);
00392 system(shellcommand);
00393 fptr=fopen(filename,"r");
00394 fscanf(fptr,"%d %lf",&NRADIALread,&RADSTEPread);
00395 if(fabs(RADSTEPread-RADSTEP)>1.0E-6 || NRADIALread!=NRADIAL){
00396 printf("Mesh in %s out of whack: RADSTEP=%g =? %g, NRADIAL=%d=?%d\n",
00397 filename,RADSTEP,RADSTEPread,NRADIAL,NRADIALread);
00398 exit(1);
00399 }
00400 for(ir=0;ir<NRADIAL;ir++){
00401 fscanf(fptr,"%lf",&aa);
00402 A[lx][ly][lz][ir]=aa;
00403 }
00404 fclose(fptr);
00405 }
00406 }
00407 }
00408 FillRemainderX();
00409
00410 }
00411
00412 void CCHArray::ReadAllA(string dirname){
00413 char filename[120],shellcommand[240];
00414 int ir,lx,ly,lz,NRADIALread;
00415 double aa,RADSTEPread;
00416 FILE *fptr;
00417
00418 for(lx=0;lx<=LMAX;lx+=dlx){
00419 for(ly=0;ly<=LMAX-lx;ly+=dly){
00420 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00421 sprintf(filename,"%s/lx%d_ly%d_lz%d.tmp",dirname.c_str(),lx,ly,lz);
00422 printf("READING: L=(%d,%d,%d), filename=%s\n",lx,ly,lz,filename);
00423 sprintf(shellcommand,
00424 "if [ ! -e %s ]; then echo Reading Error: %s, does not exist; fi",filename,filename);
00425 system(shellcommand);
00426 fptr=fopen(filename,"r");
00427 fscanf(fptr,"%d %lf",&NRADIALread,&RADSTEPread);
00428 if(fabs(RADSTEPread-RADSTEP)>1.0E-6 || NRADIALread!=NRADIAL){
00429 printf("Mesh in %s out of whack: RADSTEP=%g =? %g, NRADIAL=%d=?%d\n",
00430 filename,RADSTEP,RADSTEPread,NRADIAL,NRADIALread);
00431 exit(1);
00432 }
00433 for(ir=0;ir<NRADIAL;ir++){
00434 fscanf(fptr,"%lf\n",&aa);
00435 A[lx][ly][lz][ir]=aa;
00436 }
00437 fclose(fptr);
00438 }
00439 }
00440 }
00441 }
00442
00443 void CCHArray::PrintPars(){
00444 printf("XSYM=%d, YSYM=%d, ZSYM=%d\n",int(XSYM),int(YSYM),int(ZSYM));
00445 printf("LMAX=%d, NRADIAL=%d, RADSTEP=%g\n",LMAX,NRADIAL,RADSTEP);
00446 }
00447
00448 void CCHArray::IncrementAExpArray(double x,double y,double z,double weight){
00449 double ex,ey,ez;
00450 double r=sqrt(x*x+y*y+z*z);
00451 int ir=int(floor(r/RADSTEP));
00452 if(ir<NRADIAL){
00453 ex=x/r; ey=y/r; ez=z/r;
00454 IncrementAExpArrayFromE(ex,ey,ez,weight,ir);
00455 }
00456 }
00457
00458 void CCHArray::IncrementAExpArrayFromE(double ex,double ey,double ez,double weight,int ir){
00459 int L,lx,ly,lz;
00460 double lfact;
00461 for(lx=0;lx<=1;lx+=dlx){
00462 for(ly=0;ly<=LMAX-lx;ly+=dly){
00463 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00464 L=lx+ly+lz;
00465 lfact=chcalc->DoubleFactorial(2*L+1)/chcalc->Factorial(L);
00466 IncrementElement(lx,ly,lz,ir,
00467 weight*lfact*chcalc->GetAFromE(lx,ly,lz,ex,ey,ez));
00468 }
00469 }
00470 }
00471 FillRemainderX(ir);
00472 }
00473
00474 void CCHArray::AltIncrementAExpArrayFromE(double ex,double ey,double ez,double weight,int ir){
00475 int L,lx,ly,lz;
00476 double cL,cLL,delB,lfact;
00477 double ***B;
00478 B=new double**[2];
00479 for(lx=0;lx<2;lx++){
00480 B[lx]=new double *[LMAX+1-lx];
00481 for(ly=0;ly<=LMAX-lx;ly++){
00482 B[lx][ly]=new double[LMAX+1-lx-ly];
00483 }
00484 }
00485
00486 B[0][0][0]=1.0;
00487 IncrementElement(0,0,0,ir,weight);
00488 for(L=1;L<=LMAX;L++){
00489 lfact=chcalc->DoubleFactorial(2*L+1)/chcalc->Factorial(L);
00490 cL=1.0/double(L);
00491 cLL=1.0/(L*(2*L-1));
00492 for(lx=0;lx<2;lx++){
00493 for(ly=0;ly<=L-lx;ly++){
00494 lz=L-lx-ly;
00495 delB=0.0;
00496 if(lx>0){
00497 delB+=ex*(cL*lx-cLL*lx*(lx-1))*B[lx-1][ly][lz];
00498 }
00499 if(ly>0)
00500 delB+=ey*(cL*ly-cLL*ly*(ly-1))*B[lx][ly-1][lz];
00501 if(lz>0)
00502 delB+=ez*(cL*lz-cLL*lz*(lz-1))*B[lx][ly][lz-1];
00503 if(lx>1){
00504 delB-=ey*cLL*lx*(lx-1)*B[lx-2][ly+1][lz];
00505 delB-=ez*cLL*lx*(lx-1)*B[lx-2][ly][lz+1];
00506 }
00507 if(ly>1){
00508 if(lx>0){
00509 delB+=ex*cLL*ly*(ly-1)*(B[lx-1][ly-2][lz+2]+B[lx-1][ly][lz]);
00510 }
00511 else delB-=ex*cLL*ly*(ly-1)*B[lx+1][ly-2][lz];
00512 delB-=ez*cLL*ly*(ly-1)*B[lx][ly-2][lz+1];
00513 }
00514 if(lz>1){
00515 if(lx>0){
00516 delB+=ex*cLL*lz*(lz-1)*(B[lx-1][ly+2][lz-2]+B[lx-1][ly][lz]);
00517 }
00518 else delB-=ex*cLL*lz*(lz-1)*B[lx+1][ly][lz-2];
00519 delB-=ey*cLL*lz*(lz-1)*B[lx][ly+1][lz-2];
00520 }
00521 B[lx][ly][lz]=delB;
00522 if(lx%dlx==0 && ly%dly==0 && lz%dlz==0){
00523 IncrementElement(lx,ly,lz,ir,delB*lfact*weight);
00524 }
00525 }
00526 }
00527
00528 }
00529 for(lx=0;lx<2;lx++){
00530 for(ly=0;ly<=LMAX-lx;ly++){
00531 delete [] B[lx][ly];
00532 }
00533 delete [] B[lx];
00534 }
00535 delete [] B;
00536 }
00537
00538 double CCHArray::GetAExpElementFromMArray(int lx,int ly,int lz,int ir){
00539 int L,m,mx,my,mz;
00540 double factor,answer,lfact;
00541 L=lx+ly+lz;
00542 lfact=chcalc->DoubleFactorial(2*L+1)/chcalc->Factorial(L);
00543 answer=0.0;
00544 for(mx=0;mx<=lx/2;mx++){
00545 for(my=0;my<=ly/2;my++){
00546 for(mz=0;mz<=lz/2;mz++){
00547 m=mx+my+mz;
00548 if(m>0) factor=pow(-0.5,m);
00549 else factor=1.0;
00550 if(L>m) factor*=chcalc->DoubleFactorial(2*L-2*m-1);
00551 if(L>0) factor=factor/chcalc->DoubleFactorial(2*L-1);
00552 factor*=chcalc->Factorial(lx)/(chcalc->Factorial(lx-2*mx)*chcalc->Factorial(mx));
00553 factor*=chcalc->Factorial(ly)/(chcalc->Factorial(ly-2*my)*chcalc->Factorial(my));
00554 factor*=chcalc->Factorial(lz)/(chcalc->Factorial(lz-2*mz)*chcalc->Factorial(mz));
00555 answer+=factor*lfact*GetElement(lx-2*mx,ly-2*my,lz-2*mz,ir);
00556 }
00557 }
00558 }
00559 return answer;
00560 }
00561
00562 double CCHArray::GetMElementFromAExpArray(int lx,int ly,int lz,int ir){
00563 int mx,my,mz,m,L;
00564 double factor,answer,*lfact;
00565 L=lx+ly+lz;
00566 lfact=new double[L+1];
00567 lfact[0]=1.0;
00568 for(m=1;m<=L;m++) lfact[m]=lfact[m-1]*double(m)/double(2*m+1);
00569 answer=0.0;
00570 for(mx=0;mx<=lx/2;mx++){
00571 for(my=0;my<=ly/2;my++){
00572 for(mz=0;mz<=lz/2;mz++){
00573 m=mx+my+mz;
00574 factor=pow(0.5,m);
00575 factor=factor*chcalc->DoubleFactorial(2*L-4*m+1)/chcalc->DoubleFactorial(2*L-2*m+1);
00576 factor*=chcalc->Factorial(lx)/(chcalc->Factorial(lx-2*mx)*chcalc->Factorial(mx));
00577 factor*=chcalc->Factorial(ly)/(chcalc->Factorial(ly-2*my)*chcalc->Factorial(my));
00578 factor*=chcalc->Factorial(lz)/(chcalc->Factorial(lz-2*mz)*chcalc->Factorial(mz));
00579 answer+=factor*lfact[L-2*m]
00580 *GetElement(lx-2*mx,ly-2*my,lz-2*mz,ir);
00581 }
00582 }
00583 }
00584 delete lfact;
00585 return answer;
00586 }
00587
00588 void CCHArray::IncrementAExpArrayFromThetaPhi(double theta,double phi,double weight,int ir){
00589 double stheta,ex,ey,ez;
00590 stheta=sin(theta);
00591 ex=stheta*cos(phi);
00592 ey=stheta*sin(phi);
00593 ez=cos(theta);
00594 IncrementAExpArrayFromE(ex,ey,ez,weight,ir);
00595 }
00596
00597 void CCHArray::IncrementMArrayFromE(double ex,double ey,double ez,double weight,int ir){
00598 int lx,ly,lz;
00599 for(lx=0;lx<=LMAX;lx+=dlx){
00600 for(ly=0;ly<=LMAX-lx;ly+=dly){
00601 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00602 IncrementElement(lx,ly,lz,ir,pow(ex,lx)*pow(ey,ly)*pow(ez,lz)*weight);
00603 }
00604 }
00605 }
00606 }
00607
00608 void CCHArray::IncrementMArrayFromThetaPhi(double theta,double phi,double weight,int ir){
00609 double stheta,ex,ey,ez;
00610 stheta=sin(theta);
00611 ex=stheta*cos(phi);
00612 ey=stheta*sin(phi);
00613 ez=cos(theta);
00614 IncrementMArrayFromE(ex,ey,ez,weight,ir);
00615 }
00616
00617 void CCHArray::FillRemainderX(){
00618 for(int ir=0;ir<NRADIAL;ir++) FillRemainderX(ir);
00619 }
00620
00621 void CCHArray::FillRemainderY(){
00622 for(int ir=0;ir<NRADIAL;ir++) FillRemainderY(ir);
00623 }
00624
00625 void CCHArray::FillRemainderZ(){
00626 for(int ir=0;ir<NRADIAL;ir++) FillRemainderZ(ir);
00627 }
00628
00629 void CCHArray::FillRemainderX(int ir){
00630 int lx,ly,lz;
00631 if(LMAX>1){
00632 for(lx=2;lx<=LMAX;lx+=dlx){
00633 for(ly=0;ly<=LMAX-lx;ly+=dly){
00634 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00635 SetElement(lx,ly,lz,ir,-GetElement(lx-2,ly+2,lz,ir)-GetElement(lx-2,ly,lz+2,ir));
00636 }
00637 }
00638 }
00639 }
00640 }
00641
00642 void CCHArray::FillRemainderY(int ir){
00643 int lx,ly,lz;
00644 if(LMAX>1){
00645 for(ly=2;ly<=LMAX;ly+=dly){
00646 for(lx=0;lx<=LMAX-ly;lx+=dlx){
00647 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00648 SetElement(lx,ly,lz,ir,-GetElement(lx,ly-2,lz+2,ir)
00649 -GetElement(lx+2,ly-2,lz,ir));
00650 }
00651 }
00652 }
00653 }
00654 }
00655
00656 void CCHArray::FillRemainderZ(int ir){
00657 int lx,ly,lz;
00658 if(LMAX>1){
00659 for(lz=2;lz<=LMAX;lz+=dlz){
00660 for(lx=0;lx<=LMAX-lz;lx+=dlx){
00661 for(ly=0;ly<=LMAX-lx-lz;ly+=dly){
00662 SetElement(lx,ly,lz,ir,-GetElement(lx,ly+2,lz-2,ir)
00663 -GetElement(lx+2,ly,lz-2,ir));
00664
00665 }
00666 }
00667 }
00668 }
00669 }
00670
00671 double CCHArray::AExpand(double theta,double phi,int ir){
00672 PrintPars();
00673 double ex,ey,ez,sthet;
00674 sthet=sin(theta);
00675 ex=sthet*cos(phi);
00676 ey=sthet*sin(phi);
00677 ez=cos(theta);
00678 return AExpand(ex,ey,ez,ir);
00679 }
00680
00681 double CCHArray::AExpand(double ex,double ey,double ez,int ir){
00682 double dela,answer=0.0;
00683 int lx,ly,lz;
00684
00685 for(lx=0;lx<=LMAX;lx+=dlx){
00686 for(ly=0;ly<=LMAX-lx;ly+=dly){
00687 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00688 dela=GetElement(lx,ly,lz,ir)*pow(ex,lx)*pow(ey,ly)*pow(ez,lz);
00689 answer+=dela*chcalc->Trinomial(lx,ly,lz);
00690 }
00691 }
00692 }
00693 return answer;
00694 }
00695
00696 double CCHArray::AExpand(double x,double y,double z){
00697 double r,ex,ey,ez;
00698 int ira,irb;
00699 double w=0.0,interpolate=0.0,valuea=1.0,valueb=0.0;
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 r=sqrt(x*x+y*y+z*z);
00710 if(r<NRADIAL*RADSTEP){
00711 irb=int(floor(0.5+r/RADSTEP));
00712 ira=irb-1;
00713 ex=x/r; ey=y/r; ez=z/r;
00714 if(ira>=0 && irb<NRADIAL){
00715 valuea=AExpand(ex,ey,ez,ira);
00716 valueb=AExpand(ex,ey,ez,irb);
00717 w=((0.5+irb)*RADSTEP-r)/RADSTEP;
00718 }
00719 else if(ira<0){
00720 valuea=AExpand(-ex,-ey,-ez,0);
00721 valueb=AExpand(ex,ey,ez,irb);
00722 w=((0.5+irb)*RADSTEP-r)/RADSTEP;
00723 }
00724 else if(ira==NRADIAL){
00725 valuea=AExpand(ex,ey,ez,ira);
00726 valueb=0.0;
00727 w=((0.5+irb)*RADSTEP-r)/RADSTEP;
00728 }
00729 interpolate=w*valuea+(1.0-w)*valueb;
00730 }
00731 return interpolate;
00732 }
00733
00734 void CCHArray::RandomInit(int iseed){
00735 randy=new CRandom(iseed);
00736 }
00737
00738 void CCHArray::Randomize(double mag,int ir){
00739 int lx,ly,lz;
00740 double value;
00741 if(randy==NULL) RandomInit(-12345);
00742 for(lx=0;lx<=LMAX;lx+=dlx){
00743 for(ly=0;ly<=LMAX-lx;ly+=dly){
00744 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00745 value=(1.0-2.0*randy->ran())*mag;
00746 SetElement(lx,ly,lz,ir,value);
00747 }
00748 }
00749 }
00750 }
00751
00752 void CCHArray::Randomize(double mag){
00753 int ir;
00754 if(randy==NULL) RandomInit(-12345);
00755 for(ir=0;ir<NRADIAL;ir++){
00756 Randomize(mag,ir);
00757 }
00758 }
00759
00760 void CCHArray::RandomizeA(double mag,int ir){
00761 int lx,ly,lz;
00762 double value;
00763 if(randy==NULL) RandomInit(-12345);
00764 for(lx=0;lx<=1;lx+=dlx){
00765 for(ly=0;ly<=LMAX-lx;ly+=dly){
00766 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00767 value=(1.0-2.0*randy->ran())*mag;
00768 SetElement(lx,ly,lz,ir,value);
00769 }
00770 }
00771 FillRemainderX(ir);
00772 }
00773 }
00774
00775 void CCHArray::RandomizeA(double mag){
00776 int ir;
00777 if(randy==NULL) RandomInit(-12345);
00778 for(ir=0;ir<NRADIAL;ir++){
00779 RandomizeA(mag,ir);
00780 }
00781 }
00782
00783 void CCHArray::RandomizeA_Gaussian(double mag,int ir){
00784 int lx,ly,lz;
00785 double value;
00786 if(randy==NULL) RandomInit(-12345);
00787 for(lx=0;lx<=1;lx+=dlx){
00788 for(ly=0;ly<=LMAX-lx;ly+=dly){
00789 for(lz=0;lz<=LMAX-lx-ly;lz+=dlz){
00790 value=randy->gauss()*mag;
00791 SetElement(lx,ly,lz,ir,value);
00792 }
00793 }
00794 FillRemainderX(ir);
00795 }
00796 }
00797
00798 void CCHArray::RandomizeA_Gaussian(double mag){
00799 int ir;
00800 if(randy==NULL) RandomInit(-12345);
00801 for(ir=0;ir<NRADIAL;ir++){
00802 RandomizeA_Gaussian(mag,ir);
00803 }
00804 }
00805
00806 void CCHArray::Detrace(int ir){
00807 CCHArray *B;
00808 B=new CCHArray(LMAX,1,RADSTEP,XSYM,YSYM,ZSYM);
00809 ArrayCalc::Detrace(this,ir,B,0);
00810 ArrayCalc::CopyArray(B,0,this,ir);
00811 delete(B);
00812 }
00813
00814 void CCHArray::Detrace(){
00815 int ir;
00816 for(ir=0;ir<NRADIAL;ir++) Detrace(ir);
00817 }
00818
00819 void CCHArray::WriteShort(string filename,int LGMAX){
00820 int ir,lx,ly,lz,L;
00821 FILE *fptr;
00822 if(LGMAX>LMAX) LGMAX=LMAX;
00823 fptr=fopen(filename.c_str(),"w");
00824 fprintf(fptr,"! ");
00825 for(L=0;L<=LGMAX;L++){
00826 for(lx=0;lx<=1;lx+=dlx){
00827 for(ly=0;ly<=L-lx;ly+=dly){
00828 lz=L-lx-ly;
00829 if(lz%dlz==0)
00830 fprintf(fptr," (%d,%d,%d) ",lx,ly,lz);
00831 }
00832 }
00833 }
00834 fprintf(fptr,"\n");
00835 for(ir=0;ir<NRADIAL;ir++){
00836 fprintf(fptr,"%7.2f ",RADSTEP*(ir+0.5));
00837 for(L=0;L<=LGMAX;L++){
00838 for(lx=0;lx<=1;lx+=dlx){
00839 for(ly=0;ly<=L-lx;ly+=dly){
00840 lz=L-lx-ly;
00841 if(lz%dlz==0)
00842 fprintf(fptr," %9.2e ",GetElement(lx,ly,lz,ir));
00843 }
00844 }
00845 }
00846 fprintf(fptr,"\n");
00847 }
00848 fclose(fptr);
00849
00850 }
00851
00852 void CCHArray::PrintMoments(){
00853 int ir;
00854 double r,r2,r3,r4,norm=0.0,m1[3]={0.0},m2[3][3]={0.0};
00855 for(ir=0;ir<NRADIAL;ir++){
00856 r=(ir+0.5)*RADSTEP;
00857 r2=r*r;
00858 r3=r2*r;
00859 r4=r2*r2;
00860 norm+=r2;
00861 m1[0]+=r3*GetMElementFromAExpArray(1,0,0,ir);
00862 m1[1]+=r3*GetMElementFromAExpArray(0,1,0,ir);
00863 m1[2]+=r3*GetMElementFromAExpArray(0,0,1,ir);
00864 m2[0][0]+=r4*GetMElementFromAExpArray(2,0,0,ir);
00865 m2[1][0]+=r4*GetMElementFromAExpArray(1,1,0,ir);
00866 m2[2][0]+=r4*GetMElementFromAExpArray(1,0,1,ir);
00867 m2[1][1]+=r4*GetMElementFromAExpArray(0,2,0,ir);
00868 m2[2][1]+=r4*GetMElementFromAExpArray(0,1,1,ir);
00869 m2[2][2]+=r4*GetMElementFromAExpArray(0,0,2,ir);
00870 }
00871 m1[0]=m1[0]/norm;
00872 m1[1]=m1[1]/norm;
00873 m1[2]=m1[2]/norm;
00874 m2[0][0]=m2[0][0]/norm;
00875 m2[1][0]=m2[1][0]/norm;
00876 m2[2][0]=m2[2][0]/norm;
00877 m2[1][1]=m2[1][1]/norm;
00878 m2[2][1]=m2[2][1]/norm;
00879 m2[2][2]=m2[1][2]/norm;
00880 m2[1][2]=m2[2][1];
00881 m2[0][2]=m2[2][0];
00882 m2[0][1]=m2[1][0];
00883 }
00884 #endif