IAP GITLAB

Skip to content
Snippets Groups Projects
Commit cd6c888d authored by ralfulrich's avatar ralfulrich Committed by Ralf Ulrich
Browse files

check for particles below obs level in hybridMC

parent 2c3aac2c
No related branches found
No related tags found
No related merge requests found
...@@ -234,10 +234,21 @@ namespace corsika { ...@@ -234,10 +234,21 @@ namespace corsika {
inline std::vector<double> solve_cubic_real(long double a, long double b, long double c, inline std::vector<double> solve_cubic_real(long double a, long double b, long double c,
long double d, double const epsilon) { long double d, double const epsilon) {
CORSIKA_LOG_TRACE("cubic_2: a={:f}, b={:f}, c={:f}, d={:f}, epsilon={} {} {}", a, b, CORSIKA_LOG_TRACE("cubic_iterative: a={:f}, b={:f}, c={:f}, d={:f}, epsilon={} {} {}",
c, d, epsilon, (std::abs(a - 1) < epsilon), a, b, c, d, epsilon, (std::abs(a - 1) < epsilon),
(std::abs(b) < 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 if (std::abs(a) < epsilon) { // this is just a quadratic
return solve_quadratic_real(b, c, d, epsilon); return solve_quadratic_real(b, c, d, epsilon);
} }
...@@ -276,6 +287,10 @@ namespace corsika { ...@@ -276,6 +287,10 @@ namespace corsika {
} while ((++niter < maxiter) && (std::abs(f_x1) > epsilon)); } while ((++niter < maxiter) && (std::abs(f_x1) > epsilon));
CORSIKA_LOG_TRACE("niter={}", niter); 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); CORSIKA_LOG_TRACE("x1={} f_x1={}", x1, f_x1);
......
...@@ -35,6 +35,9 @@ namespace corsika { ...@@ -35,6 +35,9 @@ namespace corsika {
// y^3 − c*y^2 + (bd−4e)*y − b^2*e−d^2+4*c*e = 0 // 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); 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 long double y = x3[0]; // there is always at least one solution
// The essence - choosing Y with maximal absolute value. // The essence - choosing Y with maximal absolute value.
if (x3.size() == 3) { if (x3.size() == 3) {
......
...@@ -101,8 +101,8 @@ namespace corsika { ...@@ -101,8 +101,8 @@ namespace corsika {
return getLinearTrajectory(particle); return getLinearTrajectory(particle);
} }
LengthType const gyroradius = (convert_HEP_to_SI<MassType::dimension_type>(p_perp) * LengthType const gyroradius = convert_HEP_to_SI<MassType::dimension_type>(p_perp) *
constants::c / (abs(charge) * magnitudeB)); constants::c / (abs(charge) * magnitudeB);
double const maxRadians = 0.01; // maximal allowed deflection double const maxRadians = 0.01; // maximal allowed deflection
LengthType const steplimit = 2 * cos(maxRadians) * sin(maxRadians) * gyroradius; LengthType const steplimit = 2 * cos(maxRadians) * sin(maxRadians) * gyroradius;
...@@ -150,6 +150,8 @@ namespace corsika { ...@@ -150,6 +150,8 @@ namespace corsika {
auto const projectedDirectionSqrNorm = projectedDirection.getSquaredNorm(); auto const projectedDirectionSqrNorm = projectedDirection.getSquaredNorm();
bool const isParallel = (projectedDirectionSqrNorm == 0 * square(1_T)); 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) { if ((charge == 0 * constants::e) || magneticfield.getNorm() == 0_T || isParallel) {
return tracking_line::Tracking::intersect<TParticle>(particle, sphere); return tracking_line::Tracking::intersect<TParticle>(particle, sphere);
} }
...@@ -174,7 +176,10 @@ namespace corsika { ...@@ -174,7 +176,10 @@ namespace corsika {
(deltaPosLength - sphere.getRadius()) * denom / (deltaPosLength - sphere.getRadius()) * denom /
(1_m * 1_m * 1_m * 1_m); (1_m * 1_m * 1_m * 1_m);
CORSIKA_LOG_TRACE("denom={}, b={}, c={}, d={}", denom, b, c, d); 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; LengthType d_enter, d_exit;
int first = 0, first_entry = 0, first_exit = 0; int first = 0, first_entry = 0, first_exit = 0;
for (auto solution : solutions) { for (auto solution : solutions) {
......
...@@ -90,11 +90,12 @@ public: ...@@ -90,11 +90,12 @@ public:
template <typename TParticle, typename TTrack> template <typename TParticle, typename TTrack>
ProcessReturn doContinuous(TParticle const& particle, TTrack const&, bool const) { 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 n = plane_.getNormal();
auto const proj = n.dot(delta); auto const proj = n.dot(delta);
if (proj < -0_mm) { if (proj < -1_m) {
CORSIKA_LOG_INFO("particle {} failes", particle.asString()); CORSIKA_LOG_INFO("particle {} failes: proj={}, delta={}, p={}", particle.asString(),
proj, delta, particle.getPosition());
throw std::runtime_error("particle below obs level"); throw std::runtime_error("particle below obs level");
} }
return ProcessReturn::Ok; return ProcessReturn::Ok;
...@@ -115,7 +116,7 @@ using MyExtraEnv = MediumPropertyModel<UniformMagneticField<T>>; ...@@ -115,7 +116,7 @@ using MyExtraEnv = MediumPropertyModel<UniformMagneticField<T>>;
int main(int argc, char** argv) { int main(int argc, char** argv) {
logging::set_level(logging::level::info); logging::set_level(logging::level::trace);
CORSIKA_LOG_INFO("hybrid_MC"); CORSIKA_LOG_INFO("hybrid_MC");
...@@ -160,7 +161,7 @@ int main(int argc, char** argv) { ...@@ -160,7 +161,7 @@ int main(int argc, char** argv) {
unsigned short Z = std::stoi(std::string(argv[2])); unsigned short Z = std::stoi(std::string(argv[2]));
auto const mass = get_nucleus_mass(A, Z); auto const mass = get_nucleus_mass(A, Z);
const HEPEnergyType E0 = 1_GeV * std::stof(std::string(argv[3])); 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 const thetaRad = theta / 180. * M_PI;
auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
...@@ -268,8 +269,8 @@ int main(int argc, char** argv) { ...@@ -268,8 +269,8 @@ int main(int argc, char** argv) {
make_sequence(sibyllNucCounted, sibyllCounted)); make_sequence(sibyllNucCounted, sibyllCounted));
auto decaySequence = make_sequence(decayPythia, decaySibyll); auto decaySequence = make_sequence(decayPythia, decaySibyll);
auto sequence = auto sequence =
make_sequence(TrackCheck(obsPlane), hadronSequence, reset_particle_mass, make_sequence(hadronSequence, reset_particle_mass, decaySequence, eLoss, cut,
decaySequence, eLoss, cut, conex_model, longprof, observationLevel); conex_model, longprof, observationLevel, TrackCheck(obsPlane));
// define air shower object, run simulation // define air shower object, run simulation
setup::Tracking tracking; setup::Tracking tracking;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment