From cd6c888d23e92c0730b3dca4dc9ccfb63384f7a7 Mon Sep 17 00:00:00 2001 From: ralfulrich <ralf.ulrich@kit.edu> Date: Sun, 30 May 2021 19:56:38 +0200 Subject: [PATCH] check for particles below obs level in hybridMC --- .../detail/framework/utility/CubicSolver.inl | 19 +++++++++++++++++-- .../framework/utility/QuarticSolver.inl | 3 +++ .../tracking/TrackingLeapFrogCurved.inl | 11 ++++++++--- examples/hybrid_MC.cpp | 15 ++++++++------- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/corsika/detail/framework/utility/CubicSolver.inl b/corsika/detail/framework/utility/CubicSolver.inl index c15594e02..edfce0000 100644 --- a/corsika/detail/framework/utility/CubicSolver.inl +++ b/corsika/detail/framework/utility/CubicSolver.inl @@ -234,10 +234,21 @@ namespace corsika { inline std::vector<double> solve_cubic_real(long double a, long double b, long double c, long double d, double const epsilon) { - CORSIKA_LOG_TRACE("cubic_2: a={:f}, b={:f}, c={:f}, d={:f}, epsilon={} {} {}", a, b, - c, d, epsilon, (std::abs(a - 1) < epsilon), + CORSIKA_LOG_TRACE("cubic_iterative: a={:f}, b={:f}, c={:f}, d={:f}, epsilon={} {} {}", + a, b, c, d, epsilon, (std::abs(a - 1) < epsilon), (std::abs(b) < epsilon)); +#ifdef DEBUG + { + auto test = andre::solve_cubic_real_analytic(a, b, c, d, epsilon); + + for (long double test_v : test) { + CORSIKA_LOG_TRACE("test,andre x={} f(x)={}", test_v, + cubic_function(test_v, a, b, c, d)); + } + } +#endif + if (std::abs(a) < epsilon) { // this is just a quadratic return solve_quadratic_real(b, c, d, epsilon); } @@ -276,6 +287,10 @@ namespace corsika { } while ((++niter < maxiter) && (std::abs(f_x1) > epsilon)); CORSIKA_LOG_TRACE("niter={}", niter); + if (niter >= maxiter) { + CORSIKA_LOG_TRACE("failure, no solution"); + // return std::vector<double>{}; + } } CORSIKA_LOG_TRACE("x1={} f_x1={}", x1, f_x1); diff --git a/corsika/detail/framework/utility/QuarticSolver.inl b/corsika/detail/framework/utility/QuarticSolver.inl index 4562b39c0..764bc3a85 100644 --- a/corsika/detail/framework/utility/QuarticSolver.inl +++ b/corsika/detail/framework/utility/QuarticSolver.inl @@ -35,6 +35,9 @@ namespace corsika { // y^3 − c*y^2 + (bd−4e)*y − b^2*e−d^2+4*c*e = 0 std::vector<double> x3 = solve_cubic_real(1, a3, b3, c3, epsilon); + if (!x3.size()) { + return {}; // no solution, numeric problem + } long double y = x3[0]; // there is always at least one solution // The essence - choosing Y with maximal absolute value. if (x3.size() == 3) { diff --git a/corsika/detail/modules/tracking/TrackingLeapFrogCurved.inl b/corsika/detail/modules/tracking/TrackingLeapFrogCurved.inl index 1ede8cc98..749693bc7 100644 --- a/corsika/detail/modules/tracking/TrackingLeapFrogCurved.inl +++ b/corsika/detail/modules/tracking/TrackingLeapFrogCurved.inl @@ -101,8 +101,8 @@ namespace corsika { return getLinearTrajectory(particle); } - LengthType const gyroradius = (convert_HEP_to_SI<MassType::dimension_type>(p_perp) * - constants::c / (abs(charge) * magnitudeB)); + LengthType const gyroradius = convert_HEP_to_SI<MassType::dimension_type>(p_perp) * + constants::c / (abs(charge) * magnitudeB); double const maxRadians = 0.01; // maximal allowed deflection LengthType const steplimit = 2 * cos(maxRadians) * sin(maxRadians) * gyroradius; @@ -150,6 +150,8 @@ namespace corsika { auto const projectedDirectionSqrNorm = projectedDirection.getSquaredNorm(); bool const isParallel = (projectedDirectionSqrNorm == 0 * square(1_T)); + CORSIKA_LOG_TRACE("projectedDirectionSqrNorm={} T^2", + projectedDirectionSqrNorm / square(1_T)); if ((charge == 0 * constants::e) || magneticfield.getNorm() == 0_T || isParallel) { return tracking_line::Tracking::intersect<TParticle>(particle, sphere); } @@ -174,7 +176,10 @@ namespace corsika { (deltaPosLength - sphere.getRadius()) * denom / (1_m * 1_m * 1_m * 1_m); CORSIKA_LOG_TRACE("denom={}, b={}, c={}, d={}", denom, b, c, d); - std::vector<double> solutions = andre::solve_quartic_real(1, 0, b, c, d); + std::vector<double> solutions = solve_quartic_real(1, 0, b, c, d); + if (!solutions.size()) { + return tracking_line::Tracking::intersect<TParticle>(particle, sphere); + } LengthType d_enter, d_exit; int first = 0, first_entry = 0, first_exit = 0; for (auto solution : solutions) { diff --git a/examples/hybrid_MC.cpp b/examples/hybrid_MC.cpp index 159baed4f..abafdf0c3 100644 --- a/examples/hybrid_MC.cpp +++ b/examples/hybrid_MC.cpp @@ -90,11 +90,12 @@ public: template <typename TParticle, typename TTrack> ProcessReturn doContinuous(TParticle const& particle, TTrack const&, bool const) { - auto const delta = plane_.getCenter() - particle.getPosition(); + auto const delta = particle.getPosition() - plane_.getCenter(); auto const n = plane_.getNormal(); auto const proj = n.dot(delta); - if (proj < -0_mm) { - CORSIKA_LOG_INFO("particle {} failes", particle.asString()); + if (proj < -1_m) { + CORSIKA_LOG_INFO("particle {} failes: proj={}, delta={}, p={}", particle.asString(), + proj, delta, particle.getPosition()); throw std::runtime_error("particle below obs level"); } return ProcessReturn::Ok; @@ -115,7 +116,7 @@ using MyExtraEnv = MediumPropertyModel<UniformMagneticField<T>>; int main(int argc, char** argv) { - logging::set_level(logging::level::info); + logging::set_level(logging::level::trace); CORSIKA_LOG_INFO("hybrid_MC"); @@ -160,7 +161,7 @@ int main(int argc, char** argv) { unsigned short Z = std::stoi(std::string(argv[2])); auto const mass = get_nucleus_mass(A, Z); const HEPEnergyType E0 = 1_GeV * std::stof(std::string(argv[3])); - double theta = 0.; + double theta = 50.; auto const thetaRad = theta / 180. * M_PI; auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { @@ -268,8 +269,8 @@ int main(int argc, char** argv) { make_sequence(sibyllNucCounted, sibyllCounted)); auto decaySequence = make_sequence(decayPythia, decaySibyll); auto sequence = - make_sequence(TrackCheck(obsPlane), hadronSequence, reset_particle_mass, - decaySequence, eLoss, cut, conex_model, longprof, observationLevel); + make_sequence(hadronSequence, reset_particle_mass, decaySequence, eLoss, cut, + conex_model, longprof, observationLevel, TrackCheck(obsPlane)); // define air shower object, run simulation setup::Tracking tracking; -- GitLab