// ------------------------------------------------------------ // main.cc // // ------------------------------------------------------------ #define _USE_MATH_DEFINES #include #include #include #include #include #include "source/ugblock2D.h" #include "ugblock.h" #include "source/ugblock2D3D.h" using std::complex; using namespace ::_COLSAMM_; #define L2NORM(vector) sqrt(product(vector,vector).real()) #define RESTART 0 double isZero(double x) { return fabs(x) < 1e-10?1.0:0.0; } complex I(0.0,1.0); std::complex expi(double x) { return exp(I*x); } std::complex sinExp(double x) { return sin(x); } std::complex cosExp(double x) { return cos(x); } double realPart(std::complex x) { return x.real(); } double imPart(std::complex x) { return x.imag(); } double complexAngle(std::complex x) { return (std::arg(x)+2.0*M_PI); } double radiusLoch; std::complex loch(double x, double y) { if(sqrt(x*x+y*y) < radiusLoch) return 1.0; return 0.0; } double radiusGauss; double curvature; double distanceFromWaist; double lambda; double rayleighrange; std::complex gauss(double x, double y) { double k = 2.0 * M_PI / lambda; double waist = radiusGauss * sqrt(1+pow(distanceFromWaist / rayleighrange,2)); if (curvature == 0.0 || std::isnan(curvature)) { return exp(-(x*x+y*y)/(waist*waist)); } else { return exp(-(x*x+y*y)/(waist*waist))*expi(-1.0 * k * (x*x+y*y) / (2.0 * curvature)); } } std::complex spalt(double x, double y) { if(fabs(x) < radiusLoch) return 1.0; return 0.0; } double myRealSqrt(std::complex z) { return sqrt(z.real()); } std::complex myLimitToOne(std::complex in) { if (in.real() < 1.0) { return std::complex(1,0); } return in; } void CalcFresnel(std::complex (*aperture) (double x, double y), double distance, double wavenumber, VariableFFT& varIn, VariableFFT& varFar) { Blockgrid2D* blockGridRec = varFar.Give_blockgrid(); X_coordinate2d X(*blockGridRec); Y_coordinate2d Y(*blockGridRec); Function2d2,double> Aperture(aperture); Function2d1,double> Expi(expi); varFar = Aperture(X,Y) * Expi(wavenumber * (X*X+Y*Y) / (2.0 * distance)); varIn = varFar; varFar.FFT(); } void spectrumPlaneWave(std::complex (*aperture) (double x, double y), double distance, double wavenumber, VariableFFT& varIn, VariableFFT& varFar, X_coordinate2d& X, Y_coordinate2d& Y, VariableFFT& Kx, VariableFFT& Ky, VariableFFT& temp) { Blockgrid2D* blockGridRec = varFar.Give_blockgrid(); // X_coordinate2d X(*blockGridRec); // Y_coordinate2d Y(*blockGridRec); // VariableFFT Kx(varFar); // VariableFFT Ky(varFar); // double dx = varIn.getHx(); // double dy = varIn.getHy(); // double ukx = 2.0 * M_PI / varIn.getSizeX(); // double uky = 2.0 * M_PI / varIn.getSizeY(); // Kx = X / dx * ukx ; // Ky = Y / dy * uky ; Function2d2,double> Aperture(aperture); Function2d1 > absolute(ABS); Function2d1 > myRealFunc(myReal); Function2d1,double> Expi(expi); Function2d1 > Sqrt(myRealSqrt); //VariableFFT temp(varFar); temp = Sqrt(wavenumber*wavenumber - Kx*Kx - Ky*Ky) * (distance) ; std::ofstream DATEIA; DATEIA.open("varWaveK.vtk"); temp.Print_VTK(DATEIA); DATEIA.close(); //varIn = varIn * Expi(myRealFunc(temp)); varFar = Aperture(X,Y); varIn = varFar; varFar.FFT(); varFar = varFar * Expi( myRealFunc(temp)); varFar.inversFFT(); } void virtualLensCorrection(double dz, double wavenumberAverage, VariableFFT& varIn, VariableFFT& varWavenumber, VariableFFT& temp) { Function2d1,double> Expi(expi); Function2d1 > absolute(ABS); Function2d1 > myRealFunc(myReal); temp = myRealFunc(varWavenumber - wavenumberAverage ) * dz; // std::ofstream DATEIC; // DATEIC.open("varTEMPAVERAGE.vtk"); // temp.Print_VTK(DATEIC); // DATEIC.close(); // temp = myRealFunc(varWavenumber - minimumWavenmumber ) * dz; // DATEIC.open("varTEMPMINIMA.vtk"); // temp.Print_VTK(DATEIC); // DATEIC.close(); //sampling double samplingTest =Maximum(myRealFunc(temp)) ; double samplingMax = M_PI / samplingTest; if (samplingMax < 1.0) { std::cout << "undersampling \n"; std::cout << "dz = " << dz << "\n"; std::cout << "dzMax = " << samplingMax * dz << std::endl; } // std::ofstream DATEIB; // DATEIB.open("varTEMPTEST.vtk"); // temp.Print_VTK(DATEIB); // DATEIB.close(); varIn = varIn * Expi(1.0*myRealFunc(temp)); // std::ofstream DATEIA; // DATEIA.open("varInAfterCorrection.vtk"); // varIn.Print_VTK(DATEIA); // DATEIA.close(); } void powerTest(VariableFFT& varIn) { Function2d1 > absolute(ABS); double power = product(absolute(varIn),absolute(varIn)); std::cout << "power = " << power << "\n"; } void spectrumPlaneWavePropagation(double distance, double wavenumber, VariableFFT& varIn, VariableFFT& varFar, VariableFFT& Kx, VariableFFT& Ky, VariableFFT& temp ) { // Blockgrid2D* blockGridRec = varFar.Give_blockgrid(); // X_coordinate2d X(*blockGridRec); // Y_coordinate2d Y(*blockGridRec); // VariableFFT Kx(varFar); // VariableFFT Ky(varFar); // double dx = varIn.getHx(); // double dy = varIn.getHy(); // double ukx = 2.0 * M_PI / varIn.getSizeX(); // double uky = 2.0 * M_PI / varIn.getSizeY(); // Kx = X / dx * ukx ; // Ky = Y / dy * uky ; Function2d1 > MYREAL(myReal); double maxKx = Maximum(MYREAL(Kx)); double maxKy = Maximum(MYREAL(Ky)); Function2d1,double> Expi(expi); Function2d1 > Sqrt(myRealSqrt); Function2d1 > absolute(ABS); // VariableFFT temp(varIn); temp = wavenumber*wavenumber - Kx*Kx - Ky*Ky; temp = Sqrt(temp) * (distance); // std::ofstream DATEIA; // DATEIA.open("varTempA.vtk"); // temp.Print_VTK(DATEIA); // DATEIA.close(); if ((wavenumber*wavenumber - maxKx*maxKx - maxKy*maxKy) < 0) { std::cout << "warning : negative sqrt() ! decrease step size or increase resolution" << std::endl; } // varIn.FFTShift(); varIn.FFT(); //varIn.FFTShift(); // DATEIB.open("varIn.FFTShift-FFT-FFTShift.vtk"); // varIn.Print_VTK(DATEIB); // DATEIB.close(); // std::ofstream DATEIC; // DATEIC.open("varTempWithOutExp.vtk"); // temp.Print_VTK(DATEIC); // DATEIC.close(); varFar = varIn; temp = Expi( 1.0*MYREAL(temp)); varIn = varIn * temp; //varIn.FFTShift(); varIn.inversFFT(); //varIn.FFTShift(); // std::ofstream DATEID; // DATEID.open("varTempD.vtk"); // varIn.Print_VTK(DATEID); // DATEID.close(); //varFar = varFar; // varFar = varIn; } void applyLens(VariableFFT& varIn,VariableFFT& varOPL, double wavenumber = 1) { Function2d1,double> Expi(expi); Function2d1 > absolute(ABS); Function2d1 > myRealPart(realPart); varIn = varIn * Expi(-1.0*myRealPart(varOPL) * wavenumber); } double C_4; double focalLength; void estimateBeamQuality(VariableFFT& varIn, VariableFFT& Kx, VariableFFT& Ky, X_coordinate2d& X, Y_coordinate2d& Y, VariableFFT& temp, double lambda) { std::cout << "Beamquality not estimated! " << std::endl; return; Function2d1 > absolute(ABS); Function2d1 > myRealFunc(myReal); Function2d1 > winkel(complexAngle); Local_stiffness_matrix2D dx(*(varIn.Give_blockgrid())); dx.Calculate(d_dx(v_())*w_()); Local_stiffness_matrix2D dy(*(varIn.Give_blockgrid())); dy.Calculate(d_dy(v_())*w_()); CalcContinuousArg cont(*(varIn.Give_blockgrid())); int gaussIterations = 100; Variable2D f(*(varIn.Give_blockgrid())); Variable2D TEMP(*(varIn.Give_blockgrid())); Variable2D ux(*(varIn.Give_blockgrid())); Variable2D uy(*(varIn.Give_blockgrid())); Variable2D px(*(varIn.Give_blockgrid())); Variable2D py(*(varIn.Give_blockgrid())); Variable2D unity(*(varIn.Give_blockgrid())); Variable2D Intensity(*(varIn.Give_blockgrid())); Variable2D IntensityFFT(*(varIn.Give_blockgrid())); Variable2D phase(*(varIn.Give_blockgrid())); Variable2D REALPART(*(varIn.Give_blockgrid())); // X_coordinate2d X(*(varIn.Give_blockgrid())); // Y_coordinate2d Y(*(varIn.Give_blockgrid())); // VariableFFT temp(varIn); unity = 1.0; Intensity = absolute(varIn) * absolute(varIn); temp = varIn; temp.FFT(); IntensityFFT = absolute(temp) * absolute(temp); std::ofstream DATEIX; // phase = winkel(varIn) - 2.0*M_PI; // DATEIX.open("diff_phase_noncontinuous.vtk"); // phase.Print_VTK(DATEIX); // DATEIX.close(); cont.calcArg(phase,varIn); phase = phase * (-1.0); // DATEIX.open("diff_phase_from_calcArg.vtk"); // phase.Print_VTK(DATEIX); // DATEIX.close(); // DATEIX.open("diff_field.vtk"); // varIn.Print_VTK(DATEIX); // DATEIX.close(); double waveNumber = 2.0 * M_PI / lambda; phase = phase / waveNumber; //phase = phase; Local_stiffness_matrix2D helm(*(varIn.Give_blockgrid())); // also in FEA_Def and solverFEA helm.Calculate(v_()*w_()); (ux) = 0; Function2d1 > myRealPart(realPart); REALPART = (myRealPart(varIn)); f = (dy)(Intensity); for(int i=0;i> 1 : near field " << std::endl; std::cout << "Fresnelnumber ~ 1 : fresnel zone" << std::endl; std::cout << "Fresnelnumber << 1 : fraunhofer zone" << std::endl; double deltaX = geometrySize / pow(2,n-1); double deltaXFourierPlane = lambda * distance / pow(2,n-1) / deltaX; std::cout << "deltaX initial plane (z = 0) = " << deltaX << std::endl; std::cout << "deltaX fourier plane (z = " < * thermalRefractiveIndex3D = reader.give_first_variable(); Unstructured_grid *ug = new Cylinder(2,1,20); Blockgrid *bg = new Blockgrid(ug,10,10,20); Variable * thermalRefractiveIndex3D = new Variable(*bg); VariableFFT varSlice(n,n,geo); Variable2D varDoubleRefr(*(varSlice.Give_blockgrid())); IteratorZDirection zIterator(thermalRefractiveIndex3D->Give_blockgrid()); zIterator.gotoFront(); thermalRefractiveIndex3D->interpolateSlizeZ(&varDoubleRefr, &zIterator); VariableFFT varE(n,n,geo); VariableFFT varIn(varE); VariableFFT varIntensity(varE); VariableFFT varPhase(varE); VariableFFT varTempX(varE); VariableFFT varTempY(varE); VariableFFT varRefr(varE); VariableFFT varPhaseLens(varE); VariableFFT temp(varE); VariableFFT varWavenumber(varE); Blockgrid2D* blockGridRec = varE.Give_blockgrid(); X_coordinate2d X(*blockGridRec); Y_coordinate2d Y(*blockGridRec); VariableFFT Kx(varE); VariableFFT Ky(varE); double dx = varIn.getHx(); double dy = varIn.getHy(); double ukx = 2.0 * M_PI / varIn.getSizeX(); double uky = 2.0 * M_PI / varIn.getSizeY(); varTempX =(X - 0.5*dx); varTempY =(Y - 0.5*dy); Kx = varTempX / dx * ukx ; Ky = varTempY / dy * uky ; Function2d2,double> Aperture(gauss); // Function2d1,double> Expi(expi); // Function2d1 > Sqrt(myRealSqrt); //sampling criterion varE = Aperture(X,Y); std::ofstream DATEIG; DATEIG.open("/local/er96apow/FFT_results/varE___before.vtk"); varE.Print_VTK(DATEIG); DATEIG.close(); C_4 = 0.00015; //C_4 = 0.0; // std::ofstream DATEIX; // DATEIX.open("varE_bef_fft.vtk"); // varE.Print_VTK(DATEIX); // DATEIX.close(); //varE.FFT(); // std::ofstream DATEIR; // DATEIR.open("varE_fft.vtk"); // varE.Print_VTK(DATEIR); // DATEIR.close(); // varE.inversFFT(); // std::ofstream DATEIH; // DATEIH.open("varE_fft_ifft.vtk"); // varE.Print_VTK(DATEIH); // DATEIH.close(); varIn = varE; Function2d1 wurzel(sqrt); //varPhaseLens =(-1.83+1.0) * (X*X+Y*Y)/2.0 * (1.0 / R1 + 1.0 / R2) *wavenumber; varPhaseLens = (X*X + Y*Y) / 2.0 / focalLength + C_4 * ( X * X + Y * Y ) * ( X * X + Y * Y ); //varPhaseLens = (X*X + Y*Y) / 2.0 / focalLength;// + C_4 * ( X * X + Y * Y ) * ( X * X + Y * Y ); // *convergenceVariable = n_0 * wurzel(absolut( 1 - alpha * alpha * ( X * X + Y * Y ) + alpha * alpha * 4.0 * ( X * X + Y * Y ) * ( X * X + Y * Y ) )); //with C4 aberration //varPhaseLens = wurzel(X*X + Y*Y) / focalLength; Function2d1, std::complex > limitToOne(myLimitToOne); double alpha = 2.0 * M_PI / distance / 2.0 ;//200.0; alpha = alpha / 2.0; alpha = 1.0/1000.0 * 2.0 * M_PI ; varRefr = wurzel( 1.5 * 1.5 * (1.0 - alpha * alpha * (X*X+Y*Y))); // varRefr = wurzel( 1.5 * 1.5 * (1.0 - alpha * alpha * (X*X))); //varRefr = wurzel(1.8 * 1.8 * (1 - alpha * (X*X))); varRefr = limitToOne(varRefr); varWavenumber = 2.0 * M_PI * varRefr / lambda; Function2d1 > myRealFunc(myReal); std::cout << "Minimum( (myRealFunc(varRefr))) " << Minimum( (myRealFunc(varRefr))) << std::endl; std::cout << "Minimum( X) " << Minimum( (myRealFunc(X))) << std::endl; std::cout << "Maximum( X) " << Maximum( (myRealFunc(X))) << std::endl; std::cout << " Maximum( (myRealFunc(varRefr))" << Maximum( (myRealFunc(varRefr))) << std::endl; Function2d1 > absolute(ABS); double refrAverage = 0.1 * Minimum( (myRealFunc(varRefr))) + 0.9 * Maximum( (myRealFunc(varRefr))); double wavenumberAverage = 2.0 * M_PI * refrAverage / lambda; //double focalLength = 1.0 / refrAverage / alpha / sin(alpha * distance); double peroid = 2.0 * M_PI / alpha; std::cout << "focal length approx: " << focalLength<< std::endl; std::cout << "peroid length approx: " << peroid<< std::endl; std::cout << "z-dir increment: " << dz<< std::endl; // DATEIG.open("varWavenumber.vtk"); // varWavenumber.Print_VTK(DATEIG); // DATEIG.close(); // DATEIG.open("varvarPhaseLens.vtk"); // varPhaseLens.Print_VTK(DATEIG); // DATEIG.close(); // DATEIG.open("varE___before.vtk"); // varIn.Print_VTK(DATEIG); // DATEIG.close(); double dzMax = M_PI / ( sqrt(wavenumberAverage*wavenumberAverage-pow((pow(2,n)/2-1) * ukx,2)) -sqrt(wavenumberAverage*wavenumberAverage-pow((pow(2,n)/2) * ukx,2))) ; if (dzMax < dz) { std::cout << "undersampling " << std::endl; } //virtualLensCorrection(distance,wavenumberAverage,varIn,varWavenumber); applyLens(varIn, varPhaseLens,wavenumber); estimateBeamQuality(varIn,Kx,Ky,X,Y,temp,lambda); // spectrumPlaneWavePropagation(100, // wavenumber, // varIn, // varE,Kx,Ky,X,Y,temp); // DATEIG.open("varE___FFT.vtk"); // varE.Print_VTK(DATEIG); // DATEIG.close(); // DATEIG.open("varE___after.vtk"); // varIn.Print_VTK(DATEIG); // DATEIG.close(); for (int iter = 0 ; iter < distanceIncrements;iter++) { std::cout << "progress : " << double(iter) / double(distanceIncrements) * 100 << "%" << std::endl; std::ofstream DATEIQ; // DATEIQ.open("varIn____befCorrection.vtk"); // varIn.Print_VTK(DATEIQ); // DATEIQ.close(); // virtualLensCorrection(dz,wavenumberAverage,varIn,varWavenumber); // DATEIQ.open("varIn____AftCorrection.vtk"); // varIn.Print_VTK(DATEIQ); // DATEIQ.close(); spectrumPlaneWavePropagation(dz, wavenumber, varIn, varE,Kx,Ky,temp); // DATEIQ.open("varIn____AftPropagation.vtk"); // varIn.Print_VTK(DATEIQ); // DATEIQ.close(); // powerTest(varIn); //virtualLensCorrection(dz,wavenumberAverage,varIn,varWavenumber); int plotevery = 1; if (iter % plotevery == 0) { estimateBeamQuality(varIn,Kx,Ky,X,Y,temp,lambda); std::ofstream DATEIA; DATEIA.open("/local/er96apow/FFT_results/varEAtPlane_with_aberration"+std::to_string(iter *dz)+".vtk"); varIntensity = absolute(varIn) * absolute(varIn); varIntensity.Print_VTK(DATEIA); DATEIA.close(); // std::ofstream DATEIB; // DATEIB.open("varEFFT"+std::to_string(iter / plotevery)+".vtk"); // varE.Print_VTK(DATEIB); // DATEIB.close(); if (iter == 101) iter += 500; } } // VariableFFT varB(varA); /* Blockgrid2D* blockGridRec = varE.Give_blockgrid(); X_coordinate2d X(*blockGridRec); Y_coordinate2d Y(*blockGridRec); */ // CalcFresnel(loch, // distance, // wavenumber, // varIn, // varE); // spectrumPlaneWave(loch, // distance, // wavenumber, // varIn, // varE); spectrumPlaneWave(gauss, distance, wavenumber, varIn, varE,X,Y,Kx,Ky,temp); // varE = varE / L_infty( varE); std::ofstream DATEIA; DATEIA.open("varIn.vtk"); varIn.Print_VTK(DATEIA); DATEIA.close(); DATEIA.open("varE.vtk"); varE.Print_VTK(DATEIA); DATEIA.close(); // DATEIA.open("varEimag.vtk"); // varE.Print_VTK(DATEIA,imPart); // DATEIA.close(); // DATEIA.open("varEreal.vtk"); // varE.Print_VTK(DATEIA,realPart); // DATEIA.close(); cout << " Test CalcFresnel finished!!" << endl; }