コード例 #1
0
ファイル: sroptcnt.cpp プロジェクト: FranceECL/SRW
int srTCompositeOptElem::PropagateRadiationGuided(srTSRWRadStructAccessData& wfr)
{
	int numElem = (int)GenOptElemList.size();
	int numResizeInst = (int)GenOptElemPropResizeVect.size();
	const double tolRes = 1.e-04;
	int res = 0, elemCount = 0;
	for(srTGenOptElemHndlList::iterator it = GenOptElemList.begin(); it != GenOptElemList.end(); ++it)
	{
		int methNo = 0;
		int useResizeBefore = 0;
		int useResizeAfter = 0;
		double precFact = 1.;
		double underSampThresh = 0.5; //not user
		char analTreatment = 0;

		if(elemCount < numResizeInst)
		{
			srTRadResize &curPropResizeInst = GenOptElemPropResizeVect[elemCount];
			useResizeBefore = curPropResizeInst.propAutoResizeBefore();
			useResizeAfter = curPropResizeInst.propAutoResizeAfter();
			if(useResizeBefore || useResizeAfter) methNo = 2;

			precFact = curPropResizeInst.PropAutoPrec;
			analTreatment = curPropResizeInst.propAllowUnderSamp();

			//TO IMPLEMENT: eventual shift of wavefront before resizing!!!

			if((::fabs(curPropResizeInst.pxd - 1.) > tolRes) || (::fabs(curPropResizeInst.pxm - 1.) > tolRes) ||
			   (::fabs(curPropResizeInst.pzd - 1.) > tolRes) || (::fabs(curPropResizeInst.pzm - 1.) > tolRes))
				if(res = RadResizeGen(wfr, curPropResizeInst)) return res;
		}

		srTParPrecWfrPropag precParWfrPropag(methNo, useResizeBefore, useResizeAfter, precFact, underSampThresh, analTreatment);
		srTRadResizeVect auxResizeVect;
		if(res = ((srTGenOptElem*)(it->rep))->PropagateRadiation(&wfr, precParWfrPropag, auxResizeVect)) return res;
		//maybe to use "PropagateRadiationGuided" for srTCompositeOptElem?

		elemCount++;
	}
	if(elemCount < numResizeInst)
	{//post-resize
		//TO IMPLEMENT: eventual shift of wavefront before resizing!!!

		srTRadResize &postResize = GenOptElemPropResizeVect[elemCount];
		if((::fabs(postResize.pxd - 1.) > tolRes) || (::fabs(postResize.pxm - 1.) > tolRes) ||
		   (::fabs(postResize.pzd - 1.) > tolRes) || (::fabs(postResize.pzm - 1.) > tolRes))
			if(res = RadResizeGen(wfr, postResize)) return res;
	}
	return 0;
}
コード例 #2
0
ファイル: sroptdrf.cpp プロジェクト: SergeyYakubov/SRW
int srTDriftSpace::TuneRadForPropMeth_1(srTSRWRadStructAccessData* pRadAccessData, srTRadResize& PostResize)
{
	srTMomentsRatios* MomRatArray = new srTMomentsRatios[pRadAccessData->ne];
	if(MomRatArray == 0) return MEMORY_ALLOCATION_FAILURE;

	int result;
	if(pRadAccessData->Pres != 0) // Go to spatial...
		if(result = SetRadRepres(pRadAccessData, 0)) return result;

	if(result = PropagateRadMoments(pRadAccessData, MomRatArray)) return result;
	
	srTMomentsRatios* tMomRatArray = MomRatArray;

	//float pxMaxMomX = (float)(1.e-23), pxMinMomX = (float)(1.e+23), pzMaxMomX = (float)(1.e-23), pzMinMomX = (float)(1.e+23);
	//float pxMaxMomZ = (float)(1.e-23), pxMinMomZ = (float)(1.e+23), pzMaxMomZ = (float)(1.e-23), pzMinMomZ = (float)(1.e+23);
	double pxMaxMomX = (1.e-23), pxMinMomX = (1.e+23), pzMaxMomX = (1.e-23), pzMinMomX = (1.e+23); //OC130311
	double pxMaxMomZ = (1.e-23), pxMinMomZ = (1.e+23), pzMaxMomZ = (1.e-23), pzMinMomZ = (1.e+23);

	for(long ie=0; ie<pRadAccessData->ne; ie++)
	{
		if(tMomRatArray->RxxMomX > pxMaxMomX) pxMaxMomX = tMomRatArray->RxxMomX;
		if(tMomRatArray->RxxMomZ > pxMaxMomZ) pxMaxMomZ = tMomRatArray->RxxMomZ;
		if(tMomRatArray->RxxMomX < pxMinMomX) pxMinMomX = tMomRatArray->RxxMomX;
		if(tMomRatArray->RxxMomZ < pxMinMomZ) pxMinMomZ = tMomRatArray->RxxMomZ;

		if(tMomRatArray->RzzMomX > pzMaxMomX) pzMaxMomX = tMomRatArray->RzzMomX;
		if(tMomRatArray->RzzMomZ > pzMaxMomZ) pzMaxMomZ = tMomRatArray->RzzMomZ;
		if(tMomRatArray->RzzMomX < pzMinMomX) pzMinMomX = tMomRatArray->RzzMomX;
		if(tMomRatArray->RzzMomZ < pzMinMomZ) pzMinMomZ = tMomRatArray->RzzMomZ;
	
		tMomRatArray++;
	}

	//float pxMax = (pxMaxMomX > pxMaxMomZ)? pxMaxMomX : pxMaxMomZ;
	//float pxMin = (pxMinMomX < pxMinMomZ)? pxMinMomX : pxMinMomZ;
	//float pzMax = (pzMaxMomX > pzMaxMomZ)? pzMaxMomX : pzMaxMomZ;
	//float pzMin = (pzMinMomX < pzMinMomZ)? pzMinMomX : pzMinMomZ;
	double pxMax = (pxMaxMomX > pxMaxMomZ)? pxMaxMomX : pxMaxMomZ; //OC130311
	double pxMin = (pxMinMomX < pxMinMomZ)? pxMinMomX : pxMinMomZ;
	double pzMax = (pzMaxMomX > pzMaxMomZ)? pzMaxMomX : pzMaxMomZ;
	double pzMin = (pzMinMomX < pzMinMomZ)? pzMinMomX : pzMinMomZ;

	char xPostResizeUndefined = 0, zPostResizeUndefined = 0;
	if((pxMax < 0.) || (pxMin < 0.)) xPostResizeUndefined = 1;
	if((pzMax < 0.) || (pzMin < 0.)) zPostResizeUndefined = 1;

	srTRadResize RadResize;
	RadResize.pxm = RadResize.pxd = RadResize.pzm = RadResize.pzd = 1.;

	const double ResizeTol = 0.15;
	const double DiffractionFactor = 1.1;
	char xResizeNeeded = (pxMax - 1. > ResizeTol);
	char zResizeNeeded = (pzMax - 1. > ResizeTol);
	if(xResizeNeeded) RadResize.pxm = DiffractionFactor*pxMax;
	if(zResizeNeeded) RadResize.pzm = DiffractionFactor*pzMax;
	if(xResizeNeeded || zResizeNeeded) if(result = RadResizeGen(*pRadAccessData, RadResize)) return result;

	PostResize.pxm = PostResize.pzm = PostResize.pxd = PostResize.pzd = 1.;

	if(!xPostResizeUndefined)
	{
		char xPostResizeNeeded = (1.- ResizeTol > pxMax);
		if(xPostResizeNeeded) 
		{
			PostResize.pxm = pxMax;
		}
	}
	else PostResize.pxm = -1.;

	if(!zPostResizeUndefined)
	{
		char zPostResizeNeeded = (1.- ResizeTol > pzMax);
		if(zPostResizeNeeded) 
		{
			PostResize.pzm = pzMax;
		}
	}
	else PostResize.pzm = -1.;

	if(MomRatArray != 0) delete[] MomRatArray;
	return 0;
}
コード例 #3
0
ファイル: sroptdrf.cpp プロジェクト: SergeyYakubov/SRW
int srTDriftSpace::PropagateRadiationMeth_1(srTSRWRadStructAccessData* pRadAccessData)
{
	int result;
	srTRadResize PostResize;
	PostResize.pxm = PostResize.pzm = PostResize.pxd = PostResize.pzd = 1.;

	//float* OldMxxArr = new float[pRadAccessData->ne];
	double* OldMxxArr = new double[pRadAccessData->ne]; //OC130311
	if(OldMxxArr == 0) return MEMORY_ALLOCATION_FAILURE;
	//float* OldMzzArr = new float[pRadAccessData->ne];
	double* OldMzzArr = new double[pRadAccessData->ne]; //OC130311
	if(OldMzzArr == 0) return MEMORY_ALLOCATION_FAILURE;

	SetupMxxMzzArr(pRadAccessData, OldMxxArr, OldMzzArr);

	//float *NewMxxArr = 0, *NewMzzArr = 0;
	double *NewMxxArr = 0, *NewMzzArr = 0;

	if(result = TuneRadForPropMeth_1(pRadAccessData, PostResize)) return result;
	if(result = PropagateWaveFrontRadius(pRadAccessData)) return result;

	if(pRadAccessData->Pres != 1) if(result = SetRadRepres(pRadAccessData, 1)) return result;
	if(result = TraverseRadZXE(pRadAccessData)) return result;
	if(result = SetRadRepres(pRadAccessData, 0)) return result;

	//const double ResizeTol = 0.15;
	if((PostResize.pxm != -1) && (PostResize.pzm != -1))
	{
		char PostResizeNeeded = (::fabs(PostResize.pxm - 1.) || ::fabs(PostResize.pzm - 1.));
		if(PostResizeNeeded) if(result = RadResizeGen(*pRadAccessData, PostResize)) return result;
	}
	else
	{
		if(result = ComputeRadMoments(pRadAccessData)) return result;

		//NewMxxArr = new float[pRadAccessData->ne];
		NewMxxArr = new double[pRadAccessData->ne]; //OC130311
		if(NewMxxArr == 0) return MEMORY_ALLOCATION_FAILURE;
		//NewMzzArr = new float[pRadAccessData->ne];
		NewMzzArr = new double[pRadAccessData->ne];
		if(NewMzzArr == 0) return MEMORY_ALLOCATION_FAILURE;
		SetupMxxMzzArr(pRadAccessData, NewMxxArr, NewMzzArr);

		//float pxmMinE2, pxmMaxE2, pzmMinE2, pzmMaxE2;
		double pxmMinE2, pxmMaxE2, pzmMinE2, pzmMaxE2; //OC130311
		FindMinMaxRatio(OldMxxArr, NewMxxArr, pRadAccessData->ne, pxmMinE2, pxmMaxE2);
		FindMinMaxRatio(OldMzzArr, NewMzzArr, pRadAccessData->ne, pzmMinE2, pzmMaxE2);

		PostResize.pxm = PostResize.pzm = PostResize.pxd = PostResize.pzd = 1.;
		PostResize.pxm = sqrt(pxmMaxE2);
		PostResize.pzm = sqrt(pzmMaxE2);
		char PostResizeNeeded = (::fabs(PostResize.pxm - 1.) || ::fabs(PostResize.pzm - 1.));

		if(PostResizeNeeded) if(result = RadResizeGen(*pRadAccessData, PostResize)) return result;
	}

	if(result = Propagate4x4PropMatr(pRadAccessData)) return result;

	pRadAccessData->SetNonZeroWavefrontLimitsToFullRange();

	if(OldMxxArr != 0) delete[] OldMxxArr;
	if(OldMzzArr != 0) delete[] OldMzzArr;
	if(NewMxxArr != 0) delete[] NewMxxArr;
	if(NewMzzArr != 0) delete[] NewMzzArr;
	return 0;
}
コード例 #4
0
ファイル: sroptdrf.cpp プロジェクト: SergeyYakubov/SRW
int srTDriftSpace::ResizeBeforePropToWaistIfNecessary(srTSRWRadStructAccessData* pRadAccessData)
{
	int result;
	const int MinNafter = 60; // To steer
	const double DiffAllowResize = 0.05; // To steer

	double InvLambda_m = pRadAccessData->eStart*806546.577258;
	double InvLambda_m_d_Length = InvLambda_m/Length;
	double LambdaM_Length = 1./InvLambda_m_d_Length;

	double xRange = pRadAccessData->nx*pRadAccessData->xStep;
	double zRange = pRadAccessData->nz*pRadAccessData->zStep;

	double xStartAbs = ::fabs(pRadAccessData->xStart);
	double xAbsMax = ::fabs(pRadAccessData->xStart + xRange);
	if(xAbsMax < xStartAbs) xAbsMax = xStartAbs;

	double zStartAbs = ::fabs(pRadAccessData->zStart);
	double zAbsMax = ::fabs(pRadAccessData->zStart + zRange);
	if(zAbsMax < zStartAbs) zAbsMax = zStartAbs;

	double pxm = 1.4*LambdaM_Length*pRadAccessData->UnderSamplingX/(xRange*pRadAccessData->xStep); // To steer
	if(pxm < 1.) pxm = 1.;
	if(::fabs(pxm  - 1.) < DiffAllowResize) pxm = 1.;

	double pzm = 1.4*LambdaM_Length*pRadAccessData->UnderSamplingZ/(zRange*pRadAccessData->zStep); // To steer
	if(pzm < 1.) pzm = 1.;
	if(::fabs(pzm  - 1.) < DiffAllowResize) pzm = 1.;

	int NxResWell, NzResWell;
	EstimateMinNxNzBeforePropToWaist(pRadAccessData, NxResWell, NzResWell);
	double MinNxInRange = (NxResWell > MinNafter)? NxResWell : MinNafter;
	double MinNzInRange = (NzResWell > MinNafter)? NzResWell : MinNafter;

	double ResAfter_pxm = 1;
	if(pRadAccessData->pResAfter != 0) ResAfter_pxm = pRadAccessData->pResAfter->pxm;

	double pxd = ::fabs(2.3*ResAfter_pxm*xRange*pRadAccessData->xStep/(LambdaM_Length)); 
	double pxdOutOfSpot = ::fabs(2*(pRadAccessData->RobsX + Length)*xAbsMax*pRadAccessData->xStep/((pRadAccessData->RobsX)*LambdaM_Length)); 
	if(pxd < pxdOutOfSpot) pxd = pxdOutOfSpot;

	//to improve !!!

	if(::fabs(pxd - 1.) < DiffAllowResize) pxd = 1.;

	if((pRadAccessData->nx)*pxd < MinNxInRange)
	{
		pxd = MinNxInRange/double(pRadAccessData->nx);
		if(::fabs(pxd - 1.) < DiffAllowResize) pxd = 1.;
		double xRangeNew = pxd*LambdaM_Length/pRadAccessData->xStep;

		//double xRangeShouldBe = xRange*pRadAccessData->pResAfter->pxm;
		double xRangeShouldBe = xRange*ResAfter_pxm;

		if(pRadAccessData->pResAfter != 0)
		{
			pRadAccessData->pResAfter->pxm = xRangeShouldBe/xRangeNew;
			if(pRadAccessData->pResAfter->pxm > 1.) pRadAccessData->pResAfter->pxm = 1.;
		}
	}
	else
	{
		if(pRadAccessData->pResAfter != 0) pRadAccessData->pResAfter->pxm = 1.;
	}

	double ResAfter_pzm = 1;
	if(pRadAccessData->pResAfter != 0) ResAfter_pzm = pRadAccessData->pResAfter->pzm;

	double pzd = ::fabs(1.*ResAfter_pzm*zRange*pRadAccessData->zStep/(LambdaM_Length));
	double pzdOutOfSpot = ::fabs(2*(pRadAccessData->RobsZ + Length)*zAbsMax*pRadAccessData->zStep/((pRadAccessData->RobsZ)*LambdaM_Length)); 
	if(pzd < pzdOutOfSpot) pzd = pzdOutOfSpot;

	if(::fabs(pzd - 1.) < DiffAllowResize) pzd = 1.;

	if((pRadAccessData->nz)*pzd < MinNzInRange)
	{
		pzd = MinNzInRange/double(pRadAccessData->nz);
		if(::fabs(pzd - 1.) < DiffAllowResize) pzd = 1.;

		double zRangeNew = pzd*LambdaM_Length/pRadAccessData->zStep;
		//double zRangeShouldBe = zRange*pRadAccessData->pResAfter->pzm;
		double zRangeShouldBe = zRange*ResAfter_pzm;

		if(pRadAccessData->pResAfter != 0)
		{
			pRadAccessData->pResAfter->pzm = zRangeShouldBe/zRangeNew;
			if(pRadAccessData->pResAfter->pzm > 1.) pRadAccessData->pResAfter->pzm = 1.;
		}
	}
	else
	{
		if(pRadAccessData->pResAfter != 0) pRadAccessData->pResAfter->pzm = 1.;
	}

	//if((pRadAccessData->pResAfter != 0) && (::fabs(pxm - 1.) > DiffAllowResize) || (::fabs(pxd - 1.) > DiffAllowResize) || (::fabs(pzm - 1.) > DiffAllowResize) || (::fabs(pzd - 1.) > DiffAllowResize))
	if((pRadAccessData->pResAfter != 0) && ((::fabs(pxm - 1.) > DiffAllowResize) || (::fabs(pxd - 1.) > DiffAllowResize) || (::fabs(pzm - 1.) > DiffAllowResize) || (::fabs(pzd - 1.) > DiffAllowResize)))
	{
		srTRadResize Resize;
		Resize.pxd = pxd; Resize.pxm = pxm; Resize.pzd = pzd; Resize.pzm = pzm;
		//Resize.DoNotTreatSpherTerm = 1;
		Resize.doNotTreatSpherTerm(1); //OC090311

		const double PdReduceCoef = 0.95; // To steer
		long nxCurRad = pRadAccessData->nx, nzCurRad = pRadAccessData->nz;
		double MemForResize = ExtraMemSizeForResize(nxCurRad, nzCurRad, Resize.pxm, Resize.pxd, Resize.pzm, Resize.pzd, 0);
		double MemAvail = CheckMemoryAvailable(), PrevMemForResize;
		char ResolutionWasReduced = 0;
		while(MemAvail < MemForResize)
		{
			Resize.pxd *= PdReduceCoef; 
			double xRangeNew = Resize.pxd*LambdaM_Length*pRadAccessData->UnderSamplingX/pRadAccessData->xStep;

			double xRangeShouldBe = xRange*pRadAccessData->pResAfter->pxm;
			pRadAccessData->pResAfter->pxm = xRangeShouldBe/xRangeNew;
			if(pRadAccessData->pResAfter->pxm > 1.) pRadAccessData->pResAfter->pxm = 1.;
			
			Resize.pzd *= PdReduceCoef; 
			double zRangeNew = Resize.pzd*LambdaM_Length*pRadAccessData->UnderSamplingZ/pRadAccessData->zStep;

			double zRangeShouldBe = zRange*pRadAccessData->pResAfter->pzm;
			pRadAccessData->pResAfter->pzm = zRangeShouldBe/zRangeNew;
			if(pRadAccessData->pResAfter->pzm > 1.) pRadAccessData->pResAfter->pzm = 1.;

			if(Resize.pxm > 1.) Resize.pxm *= PdReduceCoef;
			if(Resize.pzm > 1.) Resize.pzm *= PdReduceCoef;

			ResolutionWasReduced = 1;
			PrevMemForResize = MemForResize;
			long nxCurRad = pRadAccessData->nx, nzCurRad = pRadAccessData->nz;
			MemForResize = ExtraMemSizeForResize(nxCurRad, nzCurRad, Resize.pxm, Resize.pxd, Resize.pzm, Resize.pzd, 0);

			if(MemForResize >= PrevMemForResize) break; // Dangerous, yet necessary to break infinite loop
		}

		double SmallLength = 0.001*Length; // To steer
		double RxOld = pRadAccessData->RobsX, RzOld = pRadAccessData->RobsZ;
		//if(::fabs(Length + RxOld) > SmallLength) Resize.DoNotTreatSpherTerm = 0;
		//if(::fabs(Length + RzOld) > SmallLength) Resize.DoNotTreatSpherTerm = 0;
		if(::fabs(Length + RxOld) > SmallLength) Resize.doNotTreatSpherTerm(0); //OC090311
		if(::fabs(Length + RzOld) > SmallLength) Resize.doNotTreatSpherTerm(0);

		//if(!(Resize.DoNotTreatSpherTerm))
		if(!(Resize.doNotTreatSpherTerm())) //OC090311
		{
			pRadAccessData->RobsX = Length*RxOld/(Length + RxOld);
			pRadAccessData->RobsZ = Length*RzOld/(Length + RzOld);
		}

				//Resize.pxm = Resize.pzm = 1;//OC

		if(result = RadResizeGen(*pRadAccessData, Resize)) return result;

		pRadAccessData->RobsX = RxOld;
		pRadAccessData->RobsZ = RzOld;

		if(ResolutionWasReduced)
		{
			CErrWarn::AddWarningMessage(&gVectWarnNos, PROPAG_PREC_REDUCED_DUE_TO_MEMORY_LIMIT);
		}
	}

	if(pRadAccessData->pResAfter != 0)
	{
		pRadAccessData->pResAfter->RelCenPosX = 0.5; // To check
		pRadAccessData->pResAfter->RelCenPosZ = 0.5;
	}

	return 0;
}