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; }
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; }
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; }
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; }