void Shade::ApplyConstrains(Beam &beam) { // apply size constrains for shade type surface real_t R2; // , ray_R2, xr, yr; R2 = Size[0]*Size[0]; // for circular shape size_t N_bad = 0; #ifdef USE_OPENMP #pragma omp parallel for reduction(+:N_bad) #endif #ifdef USING_LINUX for (size_t i = 0; i < beam.N_good_rays; ++i ) { #endif #ifdef USING_MSVC for (long long i = 0; i < beam.N_good_rays; ++i ) { #endif real_t xr = beam.X[i] - Center[0]; real_t yr = beam.Y[i] - Center[1]; switch ( Shape ) { case Surface::Circle: { real_t ray_R2 = xr*xr + yr*yr; if ( ray_R2 <= R2 ) { beam.flag[i] = 0; ++N_bad; } break; } case Surface::Rectangle: { if ( (xr >= -Size[0]/2.0) && (xr <= Size[0]/2.0) && (yr >= -Size[1]/2.0) && (yr <= Size[1]/2.0) ) { beam.flag[i] = 0; ++N_bad; } break; } } } // rearrange coordinates and cosins vectors if there are new bad rays if ( N_bad ) { if ( N_bad == beam.N_good_rays ) throw bad_surface(Surface::NoIntersections); beam.Rearrange(); } } // just auxiliary surface (used for transformation of coordinate system) Aux::Aux(): Surface(Surface::Plane,Surface::AuxType,Surface::Circle) { // cerr << "Auxiliary surface is created!\n"; }
void Surface::Intersection(Beam &beam) { RT_engine_error err; size_t N_bad = 0; // it will contain a number of rays with no surface-and-beam intersection err = surface_intersection(Class,Params.data(),beam.N_good_rays,beam.X,beam.Y,beam.Z, beam.cX,beam.cY,beam.cZ,&N_bad,beam.flag); if ( err != ENGINE_ERROR_OK ) throw bad_surface(Surface::IntersectionFailure); // rearrange coordinates and cosins vectors if there are new bad rays if ( N_bad ) { if ( N_bad == beam.N_good_rays ) throw bad_surface(Surface::NoIntersections); // cout << "N_bad = " << N_bad << "; N_good = " << beam.N_good_rays << endl; beam.Rearrange(); } }
void Lens::Action(Beam &beam) { RT_engine_error err; size_t N_bad = 0; if ( beam.N_good_rays == 0 ) throw bad_surface(Surface::NoGoodRays); err = surface_refraction(Class,Params.data(),beam.N_good_rays,beam.X,beam.Y,beam.Z, beam.cX,beam.cY,beam.cZ,beam.lambda,n1,n2,&N_bad,beam.flag); if ( err != ENGINE_ERROR_OK ) { throw bad_surface(Surface::ActionFailure); } if ( N_bad ) { if ( N_bad == beam.N_good_rays ) throw bad_surface(Surface::NoGoodRays); beam.Rearrange(); } }
void Grating::Action(Beam &beam) { RT_engine_error err; size_t N_bad = 0; if ( beam.N_good_rays == 0 ) throw bad_surface(Surface::NoGoodRays); long ord = Order[0]; err = surface_diffration(Class,Grating_Type,Params.data(),ord,Grating_constant,beam.N_good_rays, beam.X,beam.Y,beam.Z,beam.cX,beam.cY,beam.cZ,beam.lambda, n1,n2,&N_bad,beam.flag); if ( err != ENGINE_ERROR_OK ) { throw bad_surface(Surface::ActionFailure); } if ( N_bad ) { if ( N_bad == beam.N_good_rays ) throw bad_surface(Surface::NoGoodRays); beam.Rearrange(); } }
void Surface::ApplyConstrains(Beam &beam) { // apply size constrains real_t R2; // , ray_R2, xr, yr; R2 = Size[0]*Size[0]; // for circular shape size_t N_bad = 0; // cout << "\nCENTER: [" << Center[0] << ", " << Center[1] << "]\n"; // NO PARALLEL ALGORITHM HERE!!!!! #ifdef USE_OPENMP //#pragma omp parallel for reduction(+:N_bad) #pragma omp parallel for #endif #ifdef USING_LINUX for (size_t i = 0; i < beam.N_good_rays; ++i ) { #endif #ifdef USING_MSVC // OpenMP v.2 does not suppport unsigned loop counter for (long long i = 0; i < beam.N_good_rays; ++i ) { #endif real_t xr = beam.X[i] - Center[0]; real_t yr = beam.Y[i] - Center[1]; switch ( Shape ) { case Surface::Circle: { real_t ray_R2 = xr*xr + yr*yr; if ( ray_R2 > R2 ) { beam.flag[i] = 0; ++N_bad; } break; } case Surface::Rectangle: { // cout << "SIZE: [" << Size[0] << ", " << Size[1] << "]\n"; // if ( (xr < -Size[0]/2.0) || (xr > Size[0]/2.0) || // (yr < -Size[1]/2.0) || (yr > Size[1]/2.0) ) { if ( (beam.X[i] < (Center[0] -Size[0]/2.0)) || (beam.X[i] > (Center[0] +Size[0]/2.0)) || (beam.Y[i] < (Center[1] -Size[1]/2.0)) || (beam.Y[i] > (Center[1] + Size[1]/2.0)) ) { // cout << "left edge: " << Center[0] -Size[0]/2.0 << "; right edge: " << Center[0] +Size[0]/2.0 << endl; // cout << "bottom edge: " << Center[1] -Size[1]/2.0 << "; top edge: " << Center[1] +Size[1]/2.0 << endl; // cout << " beam: [" << beam.X[i] << ", " << beam.Y[i] << "]\n"; beam.flag[i] = 0; ++N_bad; } break; } } } // rearrange coordinates and cosins vectors if there are new bad rays if ( N_bad ) { // cout << " BAD RAYS: " << N_bad << endl; if ( N_bad == beam.N_good_rays ) throw bad_surface(Surface::NoIntersections); beam.Rearrange(); } } void Surface::Action(Beam &beam) { // nothing to do // cerr << "Base Surface class has no action!!!\n"; } void Surface::ApplyQE(vector<real_t> &lambda, vector<real_t> &spec) { if ( lambda.size() != spec.size() ) throw Surface::bad_surface(Surface::BadQE); RT_engine_error err = surface_QE(spec.size(),lambda.data(),spec.data(),QE); if ( err != ENGINE_ERROR_OK ) { throw Surface::bad_surface(Surface::BadQE); } } Surface::SurfaceClass Surface::GetClass() const { return Class; } Surface::SurfaceType Surface::GetType() const { return Type; } Surface::SurfaceShape Surface::GetShape() const { return Shape; } Surface::SurfaceError Surface::GetError() const { return CurrentError; } /************************************* * * * Inherited classes implementation * * * *************************************/ Plane::Plane(const SurfaceType type, const SurfaceShape shape): Surface(Surface::Plane,type,shape) { // cerr << "Plane surface is created!\n"; } /* MIRROR CLASS */ Mirror::Mirror(const SurfaceClass sclass, const SurfaceShape shape): Surface(sclass,Surface::Mirror,shape) { // cerr << "Mirror is created!\n"; } void Mirror::Action(Beam &beam) { RT_engine_error err; if ( beam.N_good_rays == 0 ) throw bad_surface(Surface::NoGoodRays); err = surface_reflection(Class,Params.data(),beam.N_good_rays, beam.X,beam.Y,beam.Z,beam.cX,beam.cY,beam.cZ); if ( err != ENGINE_ERROR_OK ) { throw bad_surface(Surface::ActionFailure); } }