IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 9bc74cc6 authored by Andre Schmidt's avatar Andre Schmidt Committed by ralfulrich
Browse files

change Steplength

parent 13841923
No related branches found
No related tags found
No related merge requests found
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <corsika/process/particle_cut/ParticleCut.h> #include <corsika/process/particle_cut/ParticleCut.h>
#include <corsika/process/proposal/ContinuousProcess.h> #include <corsika/process/proposal/ContinuousProcess.h>
#include <corsika/process/proposal/Interaction.h> #include <corsika/process/proposal/Interaction.h>
#include <corsika/process/track_writer/TrackWriter.h>
#include <corsika/process/pythia/Decay.h> #include <corsika/process/pythia/Decay.h>
#include <corsika/process/sibyll/Decay.h> #include <corsika/process/sibyll/Decay.h>
#include <corsika/process/sibyll/Interaction.h> #include <corsika/process/sibyll/Interaction.h>
...@@ -226,6 +227,7 @@ int main(int argc, char** argv) { ...@@ -226,6 +227,7 @@ int main(int argc, char** argv) {
process::on_shell_check::OnShellCheck reset_particle_mass(1.e-3, 1.e-1, false); process::on_shell_check::OnShellCheck reset_particle_mass(1.e-3, 1.e-1, false);
process::track_writer::TrackWriter trackWriter("tracks.dat");
process::longitudinal_profile::LongitudinalProfile longprof{showerAxis}; process::longitudinal_profile::LongitudinalProfile longprof{showerAxis};
Plane const obsPlane(showerCore, Vector<dimensionless_d>(rootCS, {0., 0., 1.})); Plane const obsPlane(showerCore, Vector<dimensionless_d>(rootCS, {0., 0., 1.}));
......
...@@ -214,7 +214,7 @@ namespace corsika::cascade { ...@@ -214,7 +214,7 @@ namespace corsika::cascade {
vParticle.GetEnergy() * units::constants::c; vParticle.GetEnergy() * units::constants::c;
// determine geometric tracking // determine geometric tracking
auto [step, geomMaxLength, nextVol, magMaxLength, directionBefore, directionAfter] = fTracking.GetTrack(vParticle); auto [step, geomMaxLength, nextVol] = fTracking.GetTrack(vParticle);
[[maybe_unused]] auto const& dummy_nextVol = nextVol; [[maybe_unused]] auto const& dummy_nextVol = nextVol;
// convert next_step from grammage to length // convert next_step from grammage to length
...@@ -226,18 +226,46 @@ namespace corsika::cascade { ...@@ -226,18 +226,46 @@ namespace corsika::cascade {
LengthType const distance_max = fProcessSequence.MaxStepLength(vParticle, step); LengthType const distance_max = fProcessSequence.MaxStepLength(vParticle, step);
std::cout << "distance_max=" << distance_max << std::endl; std::cout << "distance_max=" << distance_max << std::endl;
// take minimum of geometry, interaction, decay for next step // take minimum of geometry, interaction, decay, magnetic field for next step
auto const min_distance = std::min( auto const min_distance = std::min(
{distance_interact, distance_decay, distance_max, geomMaxLength, magMaxLength}); {distance_interact, distance_decay, distance_max, geomMaxLength});
C8LOG_DEBUG("transport particle by : {} m", min_distance / 1_m); C8LOG_DEBUG("transport particle by : {} m", min_distance / 1_m);
//determine displacement by the magnetic field
auto const* currentLogicalVolumeNode = vParticle.GetNode();
int chargeNumber;
if(corsika::particles::IsNucleus(vParticle.GetPID())) {
chargeNumber = vParticle.GetNuclearZ();
} else {
chargeNumber = corsika::particles::GetChargeNumber(vParticle.GetPID());
}
if(chargeNumber != 0) {
auto magneticfield = currentLogicalVolumeNode->GetModelProperties().GetMagneticField(vParticle.GetPosition());
geometry::Vector<SpeedType::dimension_type> velocity = vParticle.GetMomentum() / vParticle.GetEnergy() *
corsika::units::constants::c;
geometry::Vector<dimensionless_d> const directionBefore = velocity.normalized();
auto k = chargeNumber * corsika::units::constants::cSquared * 1_eV /
(velocity.GetNorm() * vParticle.GetEnergy() * 1_V);
LengthType const steplength = min_distance /
(directionBefore + directionBefore.cross(magneticfield) * k / 2).GetNorm();
// First Movement
//assuming magnetic field does not change during movement
auto position = vParticle.GetPosition() + directionBefore * Steplength / 2;
// Change of direction by magnetic field
geometry::Vector<dimensionless_d> const directionAfter = directionBefore + directionBefore.cross(magneticfield) *
Steplength * k;
// Second Movement
position = position + directionAfter * Steplength / 2;
geometry::Vector<dimensionless_d> const direction = (position - vParticle.GetPosition()) /
(position - vParticle.GetPosition()).GetNorm();
vParticle.SetMomentum(direction * vParticle.GetMomentum().GetNorm());
}
// here the particle is actually moved along the trajectory to new position: // here the particle is actually moved along the trajectory to new position:
// std::visit(setup::ParticleUpdate<Particle>{vParticle}, step); // std::visit(setup::ParticleUpdate<Particle>{vParticle}, step);
vParticle.SetPosition(step.PositionFromArclength(min_distance)); vParticle.SetPosition(step.PositionFromArclength(min_distance));
// .... also update time, momentum, direction, ... // .... also update time, momentum, direction, ...
vParticle.SetMomentum((directionBefore * (1 - min_distance / magMaxLength) +
directionAfter * min_distance /magMaxLength) * vParticle.GetMomentum().GetNorm());
vParticle.SetTime(vParticle.GetTime() + min_distance / units::constants::c); vParticle.SetTime(vParticle.GetTime() + min_distance / units::constants::c);
step.LimitEndTo(min_distance); step.LimitEndTo(min_distance);
...@@ -263,7 +291,7 @@ namespace corsika::cascade { ...@@ -263,7 +291,7 @@ namespace corsika::cascade {
TStackView secondaries(vParticle); TStackView secondaries(vParticle);
if (min_distance != distance_max && min_distance != magMaxLength) { if (min_distance != distance_max) {
/* /*
Create SecondaryView object on Stack. The data container Create SecondaryView object on Stack. The data container
remains untouched and identical, and 'projectil' is identical remains untouched and identical, and 'projectil' is identical
......
...@@ -20,6 +20,7 @@ set ( ...@@ -20,6 +20,7 @@ set (
UTILITIES_SOURCES UTILITIES_SOURCES
COMBoost.cc COMBoost.cc
CorsikaData.cc CorsikaData.cc
quartic.cpp
${CORSIKA_FENV}) ${CORSIKA_FENV})
set ( set (
...@@ -31,6 +32,7 @@ set ( ...@@ -31,6 +32,7 @@ set (
sgn.h sgn.h
CorsikaFenv.h CorsikaFenv.h
MetaProgramming.h MetaProgramming.h
quartic.h
) )
set ( set (
......
...@@ -15,8 +15,7 @@ ...@@ -15,8 +15,7 @@
#include <corsika/geometry/Vector.h> #include <corsika/geometry/Vector.h>
#include <corsika/particles/ParticleProperties.h> #include <corsika/particles/ParticleProperties.h>
#include <corsika/units/PhysicalUnits.h> #include <corsika/units/PhysicalUnits.h>
#include <corsika/logging/Logging.h> #include <corsika/utl/quartic.h>
#include <optional> #include <optional>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
...@@ -60,7 +59,7 @@ namespace corsika::process { ...@@ -60,7 +59,7 @@ namespace corsika::process {
<< std::endl; << std::endl;
std::cout << "TrackingLine E: " << p.GetEnergy() / 1_GeV << " GeV" << std::endl; std::cout << "TrackingLine E: " << p.GetEnergy() / 1_GeV << " GeV" << std::endl;
// determine velocity after adding magnetic field // determine direction of the particle after adding magnetic field
auto const* currentLogicalVolumeNode = p.GetNode(); auto const* currentLogicalVolumeNode = p.GetNode();
int chargeNumber; int chargeNumber;
if(corsika::particles::IsNucleus(p.GetPID())) { if(corsika::particles::IsNucleus(p.GetPID())) {
...@@ -68,39 +67,51 @@ namespace corsika::process { ...@@ -68,39 +67,51 @@ namespace corsika::process {
} else { } else {
chargeNumber = corsika::particles::GetChargeNumber(p.GetPID()); chargeNumber = corsika::particles::GetChargeNumber(p.GetPID());
} }
geometry::Vector<dimensionless_d> const directionBefore = velocity.normalized();
auto magMaxLength = 1_m/0;
auto directionAfter = directionBefore;
if(chargeNumber != 0) { if(chargeNumber != 0) {
auto magneticfield = currentLogicalVolumeNode->GetModelProperties().GetMagneticField(currentPosition); auto magneticfield = currentLogicalVolumeNode->GetModelProperties().GetMagneticField(currentPosition);
std::cout << "TrackingLine B: " << magneticfield.GetComponents() / 1_uT << " uT " << std::endl; std::cout << "TrackingLine B: " << magneticfield.GetComponents() / 1_uT << " uT " << std::endl;
geometry::Vector<SpeedType::dimension_type> const velocityVerticalMag = velocity - auto k = chargeNumber * corsika::units::constants::cSquared * 1_eV / (velocity.GetNorm() * p.GetEnergy() * 1_V);
velocity.parallelProjectionOnto(magneticfield); geometry::Vector<dimensionless_d> const directionBefore = velocity.normalized();
LengthType const gyroradius = p.GetEnergy() * velocityVerticalMag.GetNorm() * 1_V / //determine steplength to next volume
(corsika::units::constants::cSquared * abs(chargeNumber) * double a = ((directionBefore.cross(magneticfield)).dot(currentPosition - .GetCenter()) * k + 1) /
magneticfield.GetNorm() * 1_eV); ((directionBefore.cross(magneticfield)).GetSquaredNorm() * k^2 * 1_m * 1_m / 4);
//steplength depending on how exact it should be double b = directionBefore.dot(currentPosition - .GetCenter()) * 2 /
LengthType const Steplength = 0.01 * gyroradius; ((directionBefore.cross(magneticfield)).GetSquaredNorm() * k^2 * 1_m / 4);
// First Movement double c = ((currentPosition - .GetCenter()).GetSquaredNorm() - .GetRadius^2) /
auto position = currentPosition + directionBefore * Steplength / 2; ((directionBefore.cross(magneticfield)).GetSquaredNorm() * k^2 / 4);
// Change of direction by magnetic field at position std::complex<double>* solutions = solve_quartic(0, a, b, c);
magneticfield = currentLogicalVolumeNode->GetModelProperties().GetMagneticField(position); std::vector<double> tmp;
directionAfter = directionBefore + directionBefore.cross(magneticfield) * chargeNumber * for(int i = 0; i < 4; i++) {
Steplength * corsika::units::constants::cSquared * 1_eV / if(solutions[i].imag() == 0 && solutions[i].real() > 0) {
(p.GetEnergy() * velocity.GetNorm() * 1_V); tmp.push_back(solutions[i].real());
// Second Movement }
position = position + directionAfter * Steplength / 2; }
magMaxLength = (position - currentPosition).GetNorm(); LengthType const Steplength;
geometry::Vector<dimensionless_d> const direction = (position - currentPosition) / if(tmp.size() > 0) {
magMaxLength; Steplength = *std::min_element(tmp.begin(),tmp.end()) * 1_m;
velocity = direction * velocity.GetNorm(); std::cout << "s = " << Steplength << std::endl;
std::cout << "TrackingLine p: " << (direction * p.GetMomentum().GetNorm()).GetComponents() / 1_GeV } else {
<< " GeV " << std::endl; std::cout << "no intersection with anything!" << std::endl;
//what to do when this happens?
}
// First Movement
//assuming magnetic field does not change during movement
auto position = currentPosition + directionBefore * Steplength / 2;
// Change of direction by magnetic field
geometry::Vector<dimensionless_d> const directionAfter = directionBefore + directionBefore.cross(magneticfield) *
Steplength * k;
// Second Movement
position = position + directionAfter * Steplength / 2;
geometry::Vector<dimensionless_d> const direction = (position - currentPosition) /
(position - currentPosition).GetNorm();
velocity = direction * velocity.GetNorm();
std::cout << "TrackingLine p: " << (direction * p.GetMomentum().GetNorm()).GetComponents() / 1_GeV
<< " GeV " << std::endl;
} else { } else {
std::cout << "TrackingLine p: " << p.GetMomentum().GetComponents() / 1_GeV std::cout << "TrackingLine p: " << p.GetMomentum().GetComponents() / 1_GeV
<< " GeV " << std::endl; << " GeV " << std::endl;
} }
std::cout << "TrackingLine v: " << velocity.GetComponents() << std::endl; std::cout << "TrackingLine v: " << velocity.GetComponents() << std::endl;
geometry::Line line(currentPosition, velocity); geometry::Line line(currentPosition, velocity);
...@@ -166,8 +177,7 @@ namespace corsika::process { ...@@ -166,8 +177,7 @@ namespace corsika::process {
C8LOG_DEBUG(" t-intersect: {} ", min); C8LOG_DEBUG(" t-intersect: {} ", min);
return std::make_tuple(geometry::Trajectory<geometry::Line>(line, min), return std::make_tuple(geometry::Trajectory<geometry::Line>(line, min),
velocity.norm() * min, minIter->second, magMaxLength, velocity.norm() * min, minIter->second);
directionBefore, directionAfter);
} }
}; };
......
...@@ -86,7 +86,7 @@ TEST_CASE("TrackingLine") { ...@@ -86,7 +86,7 @@ TEST_CASE("TrackingLine") {
0_m / second, 1_m / second); 0_m / second, 1_m / second);
Line line(origin, v); Line line(origin, v);
auto const [traj, geomMaxLength, nextVol] = tracking.GetTrack(p); auto const [traj, geomMaxLength, nextVol, magMaxLength, beforeDirection, afterDirection] = tracking.GetTrack(p);
[[maybe_unused]] auto dummy_geomMaxLength = geomMaxLength; [[maybe_unused]] auto dummy_geomMaxLength = geomMaxLength;
[[maybe_unused]] auto dummy_nextVol = nextVol; [[maybe_unused]] auto dummy_nextVol = nextVol;
......
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