00001 #ifndef __INCLUDE_SOURCECALC_GAUSS__
00002 #define __INCLUDE_SOURCECALC_GAUSS__
00003 #include "sourcecalc.h"
00004
00005 using namespace std;
00006
00007 CSourceCalc_Gaussian::CSourceCalc_Gaussian(){
00008 InitSPars();
00009 randy=new CRandom(-1234);
00010 }
00011
00012 void CSourceCalc_Gaussian::InitSPars(){
00013
00014 parameter::set(spars,"lambda",1.0);
00015 parameter::set(spars,"Rx",4);
00016 parameter::set(spars,"Ry",4);
00017 parameter::set(spars,"Rz",4);
00018 parameter::set(spars,"Xoff",0.0);
00019 parameter::set(spars,"Yoff",0.0);
00020 parameter::set(spars,"Zoff",0.0);
00021 parameter::set(spars,"Euler_Phi",0.0);
00022 parameter::set(spars,"Euler_Theta",0.0);
00023 parameter::set(spars,"Euler_Psi",0.0);
00024 }
00025
00026 void CSourceCalc_Gaussian::SetSPars(double lambdaset,
00027 double Rxset,double Ryset,double Rzset,
00028 double Xoffset,double Yoffset,
00029 double Zoffset,double ephiset,
00030 double ethetaset,double epsiset){
00031 parameter::set(spars,"lambda",lambdaset);
00032 parameter::set(spars,"Rx",Rxset);
00033 parameter::set(spars,"Ry",Ryset);
00034 parameter::set(spars,"Rz",Rzset);
00035 parameter::set(spars,"Xoff",Xoffset);
00036 parameter::set(spars,"Yoff",Yoffset);
00037 parameter::set(spars,"Zoff",Zoffset);
00038 parameter::set(spars,"Euler_Phi",ephiset);
00039 parameter::set(spars,"Euler_Theta",ethetaset);
00040 parameter::set(spars,"Euler_Psi",epsiset);
00041 }
00042
00043 void CSourceCalc_Gaussian::SetSPars(double lambdaset,double Rxset,double Ryset,double Rzset,double Xoffset, double Yoffset,double Zoffset){
00044 parameter::set(spars,"lambda",lambdaset);
00045 parameter::set(spars,"Rx",Rxset);
00046 parameter::set(spars,"Ry",Ryset);
00047 parameter::set(spars,"Rz",Rzset);
00048 parameter::set(spars,"Xoff",Xoffset);
00049 parameter::set(spars,"Yoff",Yoffset);
00050 parameter::set(spars,"Zoff",Zoffset);
00051 }
00052 void CSourceCalc_Gaussian::SetSPars(double lambdaset,
00053 double Rxset,double Ryset,double Rzset){
00054 parameter::set(spars,"lambda",lambdaset);
00055 parameter::set(spars,"Rx",Rxset);
00056 parameter::set(spars,"Ry",Ryset);
00057 parameter::set(spars,"Rz",Rzset);
00058 }
00059
00060 void CSourceCalc_Gaussian::CalcAlpha(double **alpha,CCHArray *A){
00061 const double PI=4.0*atan(1.0);
00062 double lambda,Rx,Ry,Rz,Xoff,Yoff,Zoff;
00063 double phi,theta,psi,ctheta,cphi,cpsi,stheta,sphi,spsi;
00064 int i,j,k;
00065 double beta[4][4],gamma[4][4],off[4];
00066
00067 lambda=parameter::getD(spars,"lambda",1.0);
00068 Rx=parameter::getD(spars,"Rx",4);
00069 Ry=parameter::getD(spars,"Ry",4);
00070 Rz=parameter::getD(spars,"Rz",4);
00071
00072 Xoff=parameter::getD(spars,"Xoff",0);
00073 Yoff=parameter::getD(spars,"Yoff",0);
00074 Zoff=parameter::getD(spars,"Zoff",0);
00075
00076 phi=parameter::getD(spars,"Euler_Phi",0);
00077 theta=parameter::getD(spars,"Euler_Theta",0);
00078 psi=parameter::getD(spars,"Euler_Psi",0);
00079
00080 if(A->GetXSYM() && (fabs(Xoff)>1.0E-8 || fabs(phi)>1.0E-8
00081 || fabs(theta)>1.0E-8 || fabs(psi)>1.0E-8)){
00082 printf("Xsym true, but Xoff, Euler_phi, Euler_Theta or Euler_Psi !=0\n");
00083 exit(1);
00084 }
00085 if(A->GetYSYM() && (fabs(Yoff)>1.0E-8 || fabs(phi)>1.0E-8 ||
00086 fabs(psi)>1.0E-8)){
00087 printf("Ysym true, but Yoff, Euler_phi, or Euler_Psi !=0\n");
00088 exit(1);
00089 }
00090 if(A->GetZSYM() && fabs(theta)>1.0E-8){
00091 printf("Zsym true, but Zoff or Euler_Theta !=0\n");
00092 exit(1);
00093 }
00094
00095 ctheta=cos(theta); cphi=cos(phi); cpsi=cos(psi);
00096 stheta=sin(theta); sphi=sin(phi); spsi=sin(psi);
00097 double U[4][4],Udagger[4][4];
00098 U[1][1]=ctheta*cphi*cpsi-sphi*spsi;
00099 U[1][2]=ctheta*sphi*cpsi+cphi*spsi;
00100 U[1][3]=-stheta*cpsi;
00101 U[2][1]=-ctheta*cphi*spsi-sphi*cpsi;
00102 U[2][2]=-ctheta*sphi*spsi+cphi*cpsi;
00103 U[2][3]=stheta*spsi;
00104 U[3][1]=stheta*cphi;
00105 U[3][2]=stheta*sphi;
00106 U[3][3]=ctheta;
00107
00108 for(i=0;i<=3;i++){
00109 for(j=0;j<=3;j++){
00110 Udagger[i][j]=U[j][i];
00111 alpha[i][j]=beta[i][j]=gamma[i][j]=0.0;
00112 }
00113 }
00114
00115 gamma[1][1]=-0.25/(Rx*Rx);
00116 gamma[2][2]=-0.25/(Ry*Ry);
00117 gamma[3][3]=-0.25/(Rz*Rz);
00118
00119 for(i=1;i<=3;i++){
00120 for(j=1;j<=3;j++) beta[i][j]+=gamma[i][i]*Udagger[i][j];
00121 }
00122 for(i=1;i<=3;i++){
00123 for(j=1;j<=3;j++){
00124 for(k=1;k<=3;k++){
00125 alpha[i][j]+=U[i][k]*beta[k][j];
00126 }
00127 }
00128 }
00129
00130 off[1]=Xoff;
00131 off[2]=Yoff;
00132 off[3]=Zoff;
00133 alpha[0][0]=-log(Rx*Ry*Rz*pow(4.0*PI,1.5)/lambda);
00134 for(i=1;i<=3;i++){
00135 alpha[0][i]=0.0;
00136 for(j=1;j<=3;j++){
00137 alpha[0][i]-=2*alpha[i][j]*off[j];
00138 alpha[0][0]+=alpha[i][j]*off[i]*off[j];
00139 }
00140 alpha[i][0]=alpha[0][i];
00141 }
00142
00143 }
00144
00145 void CSourceCalc_Gaussian::CalcS(C3DArray *threed){
00146 int ix,iy,iz,isx,isy,isz;
00147 int nsx,nsy,nsz;
00148 int nxmax=threed->GetNXMAX();
00149 int nymax=threed->GetNYMAX();
00150 int nzmax=threed->GetNZMAX();
00151 double delx=threed->GetDELX();
00152 double dely=threed->GetDELY();
00153 double delz=threed->GetDELZ();
00154 double x,y,z,svalue,snorm;
00155 double lambda=parameter::getD(spars,"lambda",1.0);
00156 double Rx=parameter::getD(spars,"Rx",4);
00157 double Ry=parameter::getD(spars,"Ry",4);
00158 double Rz=parameter::getD(spars,"Rz",4);
00159 double Xoff=parameter::getD(spars,"Xoff",0);
00160 double Yoff=parameter::getD(spars,"Yoff",0);
00161 double Zoff=parameter::getD(spars,"Zoff",0);
00162 const double PI=4.0*atan(1.0);
00163 snorm=lambda*pow(4.0*PI,-1.5)/(Rx*Ry*Rz);
00164
00165 nsx=nsy=nsz=1;
00166 if(threed->GetXSYM()==0) nsx=2;
00167 if(threed->GetYSYM()==0) nsy=2;
00168 if(threed->GetZSYM()==0) nsz=2;
00169 for(isx=0;isx<nsx;isx++){
00170 for(ix=0;ix<nxmax;ix++){
00171 x=(0.5+ix)*delx;
00172 if(isx==2) x=-x;
00173 x-=Xoff;
00174 for(isy=0;isy<nsy;isy++){
00175 for(iy=0;iy<nymax;iy++){
00176 y=(0.5+iy)*dely;
00177 if(isy==1) y=-y;
00178 y-=Yoff;
00179 for(isz=0;isz<nsz;isz++){
00180 for(iz=0;iz<nzmax;iz++){
00181 z=(0.5+iz)*delz;
00182 if(isz==1) z=-z;
00183 z-=Zoff;
00184 svalue=exp(-0.25*((x*x/(Rx*Rx))+(y*y/(Ry*Ry))+(z*z/(Rz*Rz))));
00185 threed->SetElement(isx,ix,isy,iy,isz,iz,snorm*svalue);
00186 }
00187 }
00188 }
00189 }
00190 }
00191 }
00192 }
00193
00194 void CSourceCalc_Gaussian::CalcS(CCHArray *A){
00195 int i,ir;
00196 int GNMAX,NRADIAL;
00197 double **alpha;
00198 double r,DELR,norm;
00199 CCHArray *b,*bb,*C,*oldC;
00200 bool XSYM,YSYM,ZSYM;
00201 XSYM=A->GetXSYM();
00202 YSYM=A->GetYSYM();
00203 ZSYM=A->GetZSYM();
00204 GNMAX=40;
00205 NRADIAL=A->GetNRADIAL();
00206 DELR=A->GetRADSTEP();
00207 C=new CCHArray(GNMAX,1,DELR,XSYM,YSYM,ZSYM);
00208 oldC=new CCHArray(GNMAX,1,DELR,XSYM,YSYM,ZSYM);
00209 b=new CCHArray(2,1,DELR,XSYM,YSYM,ZSYM);
00210 bb=new CCHArray(2,1,DELR,XSYM,YSYM,ZSYM);
00211 alpha=new double *[4];
00212 for(i=0;i<4;i++) alpha[i]=new double[4];
00213
00214 CalcAlpha(alpha,A);
00215 norm=exp(alpha[0][0]);
00216
00217 for(ir=0;ir<NRADIAL;ir++){
00218 r=DELR*(0.5+ir);
00219
00220 b->SetElement(0,0,0,0,0.0);
00221
00222 if(!XSYM)
00223 b->SetElement(1,0,0,0,r*alpha[1][0]);
00224 if(!YSYM)
00225 b->SetElement(0,1,0,0,r*alpha[2][0]);
00226 if(!ZSYM)
00227 b->SetElement(0,0,1,0,r*alpha[3][0]);
00228
00229 b->SetElement(2,0,0,0,r*r*alpha[1][1]);
00230 if(!XSYM && !YSYM)
00231 b->SetElement(1,1,0,0,r*r*alpha[1][2]);
00232 if(!XSYM && !ZSYM)
00233 b->SetElement(1,0,1,0,r*r*alpha[1][3]);
00234 b->SetElement(0,2,0,0,r*r*alpha[2][2]);
00235 if(!YSYM && !ZSYM)
00236 b->SetElement(0,1,1,0,r*r*alpha[2][3]);
00237 b->SetElement(0,0,2,0,r*r*alpha[3][3]);
00238
00239 ArrayCalc::Detrace(b,0,bb,0);
00240
00241 ArrayCalc::CalcAExpArrayFromXExpArray(bb,0,A,ir);
00242 A->ScaleArray(norm,ir);
00243 A->FillRemainderX(ir);
00244 }
00245 for(i=0;i<4;i++) delete [] alpha[i];
00246 delete [] alpha;
00247 delete(C);
00248 delete(oldC);
00249 delete(b);
00250 delete(bb);
00251 }
00252
00253 void CSourceCalc_Gaussian::GaussCFCalc(C3DArray *cf3d){
00254 int ix,iy,iz,isx,isy,isz;
00255 int nxmax=cf3d->GetNXMAX();
00256 int nymax=cf3d->GetNYMAX();
00257 int nzmax=cf3d->GetNZMAX();
00258 double delqx=cf3d->GetDELX();
00259 double delqy=cf3d->GetDELY();
00260 double delqz=cf3d->GetDELZ();
00261 double qx,qy,qz;
00262 double lambda=parameter::getD(spars,"lambda",1.0);
00263 double Rx=parameter::getD(spars,"Rx",4);
00264 double Ry=parameter::getD(spars,"Ry",4);
00265 double Rz=parameter::getD(spars,"Rz",4);
00266 double svalue;
00267 isx=isy=isz=0;
00268 for(ix=0;ix<nxmax;ix++){
00269 qx=(0.5+ix)*delqx;
00270 for(iy=0;iy<nymax;iy++){
00271 qy=(0.5+iy)*delqy;
00272 for(iz=0;iz<nzmax;iz++){
00273 qz=(0.5+iz)*delqz;
00274 svalue=exp((-4*qx*qx*Rx*Rx-4*qy*qy*Ry*Ry-4*qz*qz*Rz*Rz)/(HBARC*HBARC));
00275 cf3d->SetElement(isx,ix,isy,iy,isz,iz,lambda*svalue);
00276 }
00277 }
00278 }
00279 }
00280
00281 #endif