int srTIsotrSrc::CreateWavefrontElField(srTSRWRadStructAccessData& RadAccessData) {// m, eV ! int result; const double TwoPI = 6.28318530717959; const double InvTwoPI = 1./TwoPI; if(result = CheckInputConsistency()) return result; SetupSourceConstants(); double LongDistE2 = LongDist*LongDist; double LongDistE3 = LongDistE2*LongDist; double Inv_ye2 = 1./LongDistE2; double enMult = (2.53384080189E+06)*LongDist; float* tRadX = RadAccessData.pBaseRadX; float* tRadZ = RadAccessData.pBaseRadZ; double z = RadAccessData.zStart - z0; for(int iz=0; iz<RadAccessData.nz; iz++) { double ze2 = z*z; double x = RadAccessData.xStart - x0; for(int ix=0; ix<RadAccessData.nx; ix++) { double xe2 = x*x; double a = (xe2 + ze2)*Inv_ye2; double CoordPhaseTerm = enMult*a*(1 - 0.25*a + 0.125*a*a); double en = RadAccessData.eStart; for(int ie=0; ie<RadAccessData.ne; ie++) { double Phase = en*CoordPhaseTerm; //Phase -= TwoPI*long(Phase*InvTwoPI); Phase -= TwoPI*((long long)(Phase*InvTwoPI)); double CosPh = cos(Phase), SinPh = sin(Phase); double R2 = LongDistE2 + xe2 + ze2; double GeomFact = LongDistE3/(R2*sqrt(R2)); double NormConst = NormConstElField*GeomFact; double ReA = NormConst*CosPh, ImA = NormConst*SinPh; SetupProperPolariz(ReA, ImA, tRadX, tRadZ); tRadX += 2; tRadZ += 2; en += RadAccessData.eStep; } x += RadAccessData.xStep; } z += RadAccessData.zStep; } return 0; }
int srTRadIntPowerDensity::ComputeTotalPowerDensityDistr(srTPowDensStructAccessData& PowDensAccessData) { int result; if(result = CheckInputConsistency()) return result; MagFieldIsConstG = TrjHndl.rep->MagFieldIsConstant(); srTGenTrjHndl hGenTrjLoc = TrjHndl; if(MagFieldIsConstG && (IntPowDenPrec.Method == 1)) // Const. Magnetic Field and Near Field comp. method { char Periodicity = 1; // non-periodic if(result = hGenTrjLoc.rep->ConvertToArbTrjDat(Periodicity, DistrInfoDat, TrjHndl)) return result; MagFieldIsConstG = 0; } if(MagFieldIsConstG) SetupNativeRotation(); int MagType = TrjHndl.rep->MagFieldPeriodicity(); if((IntPowDenPrec.Method == 2) && (MagType == 2)) // far-field & periodic { LongIntTypeG = 2; // integration over one period } else { LongIntTypeG = 1; // integration over total range } DistrInfoDat.AssumeAllPhotonEnergies = 1; // for correct determination of the integration limits //if(result = TrjHndl.rep->ShowLimitsAndInitInteg(DistrInfoDat, LongIntTypeG, sIntegStartG, sIntegFinG, AmOfPerG)) return result; if(result = TrjHndl.rep->ShowLimitsAndInitInteg(DistrInfoDat, LongIntTypeG, sIntegStartG, sIntegFinG, AmOfPerG, false)) return result; //OC030412 don't calculate interpolating structure since it was already calculated outside if(IntPowDenPrec.UseSpecIntLim) { if(sIntegStartG < IntPowDenPrec.sStart) sIntegStartG = IntPowDenPrec.sStart; if(sIntegFinG > IntPowDenPrec.sFin) sIntegFinG = IntPowDenPrec.sFin; } if(((sIntegStartG > DistrInfoDat.yStart) || (sIntegFinG > DistrInfoDat.yStart)) && (IntPowDenPrec.Method == 1)) { CErrWarn::AddWarningMessage(&gVectWarnNos, OBSERV_POINT_TOO_CLOSE_TO_INTEG_LIMITS); } if(DistrInfoDat.obsPlaneIsTransv) { if(result = TryToReduceIntegLimits()) return result; } sIntegRelPrecG = 0.06/IntPowDenPrec.PrecFact; // To steer DisposeAuxTrjArrays(); MaxFluxDensValG = 0.; if(MagFieldIsConstG) { double ElEn = TrjHndl.rep->EbmDat.Energy; double Robs = DistrInfoDat.yStart - TrjHndl.rep->EbmDat.s0; ActNormConstG = 18.11*ElEn*ElEn*ElEn*ElEn*ElEn*(TrjHndl.rep->EbmDat.Current)/(RmaG*Robs*Robs); } else { double Gam = TrjHndl.rep->EbmDat.Gamma; ActNormConstG = (9.167170453E-16)*Gam*Gam*Gam*Gam*Gam*Gam*(TrjHndl.rep->EbmDat.Current); // To make result in W/mm^2 } gmTrans trfObsPl; bool trfObsPlaneIsDefined = DistrInfoDat.SetupTrfObsPlaneIfNecessary(trfObsPl); double *pObSurfData = PowDensAccessData.m_spObSurfData.rep; bool obSurfIsDefined = (pObSurfData != 0); TVector3d &vExP = DistrInfoDat.vHor, &vEyP = DistrInfoDat.vLong, vEzP, vEyP0, vExP0; char FinalResAreSymOverX = 0, FinalResAreSymOverZ = 0; if((!trfObsPlaneIsDefined) && (!obSurfIsDefined)) AnalizeFinalResultsSymmetry(FinalResAreSymOverX, FinalResAreSymOverZ); //to make more general double xc = TrjHndl.rep->EbmDat.dxds0*(DistrInfoDat.yStart - TrjHndl.rep->EbmDat.s0) + TrjHndl.rep->EbmDat.x0; double zc = TrjHndl.rep->EbmDat.dzds0*(DistrInfoDat.yStart - TrjHndl.rep->EbmDat.s0) + TrjHndl.rep->EbmDat.z0; double xStep = (DistrInfoDat.nx > 1)? (DistrInfoDat.xEnd - DistrInfoDat.xStart)/(DistrInfoDat.nx - 1) : 0.; double zStep = (DistrInfoDat.nz > 1)? (DistrInfoDat.zEnd - DistrInfoDat.zStart)/(DistrInfoDat.nz - 1) : 0.; double xTol = xStep*0.001; // To steer double zTol = zStep*0.001; // To steer double xStart = DistrInfoDat.xStart; double zStart = DistrInfoDat.zStart; if(trfObsPlaneIsDefined) {//definition in local frame xStart = -0.5*(DistrInfoDat.xEnd - DistrInfoDat.xStart); zStart = -0.5*(DistrInfoDat.zEnd - DistrInfoDat.zStart); } //TVector3d vCenSurf(0.5*(DistrInfoDat.xStart + DistrInfoDat.xEnd), DistrInfoDat.yStart, 0.5*(DistrInfoDat.zStart + DistrInfoDat.zEnd)); //if(obSurfIsDefined) //{ // vCenSurf.y = CGenMathMeth::interpFunc2D(vCenSurf.x, vCenSurf.z, DistrInfoDat.xStart, DistrInfoDat.xEnd, DistrInfoDat.nx, DistrInfoDat.zStart, DistrInfoDat.zEnd, DistrInfoDat.nz, pObSurfData); //} long PerZ = DistrInfoDat.nx; long TotalAmOfOutPoints = DistrInfoDat.nz*DistrInfoDat.nx; if(FinalResAreSymOverX) TotalAmOfOutPoints >>= 1; if(FinalResAreSymOverZ) TotalAmOfOutPoints >>= 1; long PointCount = 0; double UpdateTimeInt_s = 0.5; srTCompProgressIndicator CompProgressInd(TotalAmOfOutPoints, UpdateTimeInt_s); TVector3d vRlab(0, 0, 0), vRloc(0, 0, 0); double yStartOrig = DistrInfoDat.yStart; for(int iz=0; iz<DistrInfoDat.nz; iz++) { //EXZ.z = DistrInfoDat.zStart + iz*zStep; EXZ.z = zStart + iz*zStep; //OC140110 vRloc.z = EXZ.z; if(FinalResAreSymOverZ) { if((EXZ.z - zc) > zTol) break;} for(int ix=0; ix<DistrInfoDat.nx; ix++) { //EXZ.x = DistrInfoDat.xStart + ix*xStep; EXZ.x = xStart + ix*xStep; //OC140110 if(trfObsPlaneIsDefined) { if(obSurfIsDefined) { //Deviation of Long. coord of obs. point without a space transform.: vRloc.y = CGenMathMeth::tabTangOrtsToSurf2D(vExP0, vEzP, ix, iz, DistrInfoDat.nx, DistrInfoDat.nz, xStep, zStep, pObSurfData); vEyP0 = vEzP^vExP0; //vLong before space transform. vEyP = trfObsPl.TrBiPoint(vEyP0); //vLong after space transform., to be used in PowDensFun vExP = trfObsPl.TrBiPoint(vExP0); //vHor after space transform. } vRloc.x = EXZ.x; //if there is no surface, vRloc.y should be 0 - is it correct? vRlab = trfObsPl.TrPoint(vRloc); EXZ.x = vRlab.x; EXZ.z = vRlab.z; DistrInfoDat.yStart = vRlab.y; } else { if(obSurfIsDefined) { //DistrInfoDat.yStart = CGenMathMeth::tabFunc2D(ix, iz, DistrInfoDat.nx, pObSurfData); DistrInfoDat.yStart = yStartOrig + CGenMathMeth::tabTangOrtsToSurf2D(vExP, vEzP, ix, iz, DistrInfoDat.nx, DistrInfoDat.nz, xStep, zStep, pObSurfData); vEyP = vEzP^vExP; //defines vLong, to be used in PowDensFun //TVector3d mRow1(vExP.x, vEyP.x, vEzP.x); //TVector3d mRow2(vExP.y, vEyP.y, vEzP.y); //TVector3d mRow3(vExP.z, vEyP.z, vEzP.z); //TMatrix3d M(mRow1, mRow2, mRow3); //trfObsPl.SetMatrixVector(M, vCenSurf); } } if(FinalResAreSymOverX) { if((EXZ.x - xc) > xTol) break;} if(MagFieldIsConstG) { PobsLocG.x = EXZ.x; PobsLocG.y = 0.; PobsLocG.z = EXZ.z; PobsLocG = TrLab2Loc.TrPoint(PobsLocG); } float* pPowDens = PowDensAccessData.pBasePowDens + iz*PerZ + ix; if(result = ComputePowerDensityAtPoint(pPowDens)) return result; DistrInfoDat.yStart = yStartOrig; if(result = srYield.Check()) return result; if(result = CompProgressInd.UpdateIndicator(PointCount++)) return result; } } if(FinalResAreSymOverZ || FinalResAreSymOverX) FillInSymPartsOfResults(FinalResAreSymOverX, FinalResAreSymOverZ, PowDensAccessData); //To make this optional? if(result = TreatFiniteElecBeamEmittance(PowDensAccessData, &trfObsPl)) return result; //to take into accout eventual tilt of the observation plane! return 0; }