示例#1
0
文件: srisosrc.cpp 项目: vstanic/SRW
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;
}
示例#2
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;
}