IAP GITLAB

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

added function for magnetic step

parent c8031e21
No related branches found
No related tags found
No related merge requests found
...@@ -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 [stepWithoutB, stepWithB, geomMaxLength, nextVol] = fTracking.GetTrack(vParticle); auto [lineWithoutB, stepWithoutB, stepWithB, 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
...@@ -232,41 +232,16 @@ namespace corsika::cascade { ...@@ -232,41 +232,16 @@ namespace corsika::cascade {
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 // determine displacement by the magnetic field
auto const* currentLogicalVolumeNode = vParticle.GetNode(); auto [line, position, directionAfter] = fTracking.MagneticStep(vParticle, lineWithoutB, min_distance);
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();
int chargeNumber;
if (corsika::particles::IsNucleus(vParticle.GetPID())) {
chargeNumber = vParticle.GetNuclearZ();
} else {
chargeNumber = corsika::particles::GetChargeNumber(vParticle.GetPID());
}
auto k = chargeNumber * corsika::units::constants::cSquared * 1_eV /
(velocity.GetNorm() * vParticle.GetEnergy() * 1_V);
// First Movement
// assuming magnetic field does not change during movement
auto position = vParticle.GetPosition() + directionBefore * min_distance / 2;
// Change of direction by magnetic field
geometry::Vector<dimensionless_d> const directionAfter = directionBefore + directionBefore.cross(magneticfield) *
min_distance * k;
// Second Movement
position = position + directionAfter * min_distance / 2;
auto distance = position - vParticle.GetPosition(); auto distance = position - vParticle.GetPosition();
// distance.norm() != min_distance if q != 0 // distance.norm() != min_distance if q != 0
// small error can be neglected // small error can be neglected
if (distance.norm() != 0_m) {
velocity = distance.normalized() * velocity.norm();
} // no velocity update for very small steps
// 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.SetMomentum(directionAfter.normalized() * vParticle.GetMomentum().norm()); vParticle.SetMomentum(directionAfter.normalized() * vParticle.GetMomentum().norm());
geometry::Line line(vParticle.GetPosition(), velocity); geometry::Trajectory<geometry::Line> stepNew(line, distance.norm() / line.GetV0().norm());
geometry::Trajectory<geometry::Line> stepNew(line, distance.norm() / velocity.norm());
vParticle.SetPosition(position); vParticle.SetPosition(position);
vParticle.SetTime(vParticle.GetTime() + distance.norm() / units::constants::c); vParticle.SetTime(vParticle.GetTime() + distance.norm() / units::constants::c);
std::cout << "New Position: " << vParticle.GetPosition().GetCoordinates() << std::endl; std::cout << "New Position: " << vParticle.GetPosition().GetCoordinates() << std::endl;
......
...@@ -62,6 +62,8 @@ namespace corsika::process { ...@@ -62,6 +62,8 @@ namespace corsika::process {
<< " 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);
auto const* currentLogicalVolumeNode = p.GetNode(); auto const* currentLogicalVolumeNode = p.GetNode();
//~ auto const* currentNumericalVolumeNode = //~ auto const* currentNumericalVolumeNode =
//~ fEnvironment.GetUniverse()->GetContainingNode(currentPosition); //~ fEnvironment.GetUniverse()->GetContainingNode(currentPosition);
...@@ -86,8 +88,7 @@ namespace corsika::process { ...@@ -86,8 +88,7 @@ namespace corsika::process {
std::cout << " Magnetic Field: " << magneticfield.GetComponents() / 1_uT << " uT " << std::endl; std::cout << " Magnetic Field: " << magneticfield.GetComponents() / 1_uT << " uT " << std::endl;
auto k = chargeNumber * corsika::units::constants::cSquared * 1_eV / (velocity.GetNorm() * p.GetEnergy() * 1_V); auto k = chargeNumber * corsika::units::constants::cSquared * 1_eV / (velocity.GetNorm() * p.GetEnergy() * 1_V);
geometry::Vector<dimensionless_d> const directionBefore = velocity.normalized(); geometry::Vector<dimensionless_d> const directionBefore = velocity.normalized();
geometry::Vector<SpeedType::dimension_type> velocity1 = velocity; LengthType Steplength = 10_m; // length irrelevant if q=0 and else it gets changed again
geometry::Vector<SpeedType::dimension_type> velocity2 = velocity;
// for entering from outside // for entering from outside
auto addIfIntersects = [&](auto const& vtn) { auto addIfIntersects = [&](auto const& vtn) {
...@@ -114,7 +115,6 @@ namespace corsika::process { ...@@ -114,7 +115,6 @@ namespace corsika::process {
std::cout << "Solutions for next Volume: " << solutions[i].real() << std::endl; std::cout << "Solutions for next Volume: " << solutions[i].real() << std::endl;
} }
} }
LengthType Steplength;
if (tmp.size() > 0) { if (tmp.size() > 0) {
Steplength = 1_m * *std::min_element(tmp.begin(),tmp.end()); Steplength = 1_m * *std::min_element(tmp.begin(),tmp.end());
std::cout << "Steplength to next volume = " << Steplength << std::endl; std::cout << "Steplength to next volume = " << Steplength << std::endl;
...@@ -123,23 +123,15 @@ namespace corsika::process { ...@@ -123,23 +123,15 @@ namespace corsika::process {
// what to do when this happens? (very unlikely) // what to do when this happens? (very unlikely)
} }
delete [] solutions; delete [] solutions;
// First Movement }
// assuming magnetic field does not change during movement
auto position = currentPosition + directionBefore * Steplength / 2; auto [line1, position, direction] = MagneticStep(p, line, Steplength);
// Change of direction by magnetic field // new particle position and direction not needed in this case
geometry::Vector<dimensionless_d> const directionAfter = directionBefore + directionBefore.cross(magneticfield) * // instead of changing the line with magnetic field, the TimeOfIntersection() could be changed
Steplength * k;
// Second Movement
position = position + directionAfter * Steplength / 2;
geometry::Vector<dimensionless_d> const direction = (position - currentPosition) /
(position - currentPosition).GetNorm();
velocity1 = direction * velocity.GetNorm();
} // instead of changing the line with magnetic field, the TimeOfIntersection() could be changed
// using line has some errors for huge steps // using line has some errors for huge steps
geometry::Line line(currentPosition, velocity1);
if (auto opt = TimeOfIntersection(line, sphere); opt.has_value()) { if (auto opt = TimeOfIntersection(line1, sphere); opt.has_value()) {
auto const [t1, t2] = *opt; auto const [t1, t2] = *opt;
C8LOG_DEBUG("intersection times: {} s; {} s", t1 / 1_s, t2 / 1_s); C8LOG_DEBUG("intersection times: {} s; {} s", t1 / 1_s, t2 / 1_s);
if (t1.magnitude() > 0) if (t1.magnitude() > 0)
...@@ -178,34 +170,26 @@ namespace corsika::process { ...@@ -178,34 +170,26 @@ namespace corsika::process {
} }
LengthType Steplength; LengthType Steplength;
if (tmp.size() > 0) { if (tmp.size() > 0) {
Steplength = 1_m * *std::min_element(tmp.begin(),tmp.end()); Steplength = 1_m * *std::min_element(tmp.begin(),tmp.end());
if (numericallyInside == false) { if (numericallyInside == false) {
int p = std::min_element(tmp.begin(),tmp.end()) - tmp.begin(); int p = std::min_element(tmp.begin(),tmp.end()) - tmp.begin();
tmp.erase(tmp.begin() + p); tmp.erase(tmp.begin() + p);
Steplength = 1_m * *std::min_element(tmp.begin(),tmp.end()); Steplength = 1_m * *std::min_element(tmp.begin(),tmp.end());
} }
std::cout << "steplength out of current volume = " << Steplength << std::endl; std::cout << "steplength out of current volume = " << Steplength << std::endl;
} else { } else {
std::cout << "no intersection (2)!" << std::endl; std::cout << "no intersection (2)!" << std::endl;
// what to do when this happens? (very unlikely) // what to do when this happens? (very unlikely)
} }
delete [] solutions; delete [] solutions;
}
// First Movement auto [line2, position, direction] = MagneticStep(p, line, Steplength);
// assuming magnetic field does not change during movement // new particle position and direction not needed in this case
auto position = currentPosition + directionBefore * Steplength / 2; // instead of changing the line with magnetic field, the TimeOfIntersection() could be changed
// Change of direction by magnetic field // using line has some errors for huge steps
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();
velocity2 = direction * velocity.GetNorm();
} // instead of changing the line with magnetic field, the TimeOfIntersection() could be changed
geometry::Line line(currentPosition, velocity2);
[[maybe_unused]] auto const [t1, t2] = *TimeOfIntersection(line, sphere); [[maybe_unused]] auto const [t1, t2] = *TimeOfIntersection(line2, sphere);
[[maybe_unused]] auto dummy_t1 = t1; [[maybe_unused]] auto dummy_t1 = t1;
intersections.emplace_back(t2, currentLogicalVolumeNode->GetParent()); intersections.emplace_back(t2, currentLogicalVolumeNode->GetParent());
} }
...@@ -228,26 +212,49 @@ namespace corsika::process { ...@@ -228,26 +212,49 @@ namespace corsika::process {
<< min << min
// << " " << minIter->second->GetModelProperties().GetName() // << " " << minIter->second->GetModelProperties().GetName()
<< std::endl; << std::endl;
auto [lineWithB, position, direction] = MagneticStep(p, line, velocity.norm() * min);
// new particle position and direction not needed in this case
return std::make_tuple(line, geometry::Trajectory<geometry::Line>(line, min),
geometry::Trajectory<geometry::Line>(lineWithB, min),
velocity.norm() * min, minIter->second);
}
template <typename Particle> // was Stack previously, and argument was
// Stack::StackIterator
// determine direction of the particle after adding magnetic field
auto MagneticStep(Particle const& p, corsika::geometry::Line line, corsika::units::si::LengthType Steplength) {
using namespace corsika::units::si;
//charge of the particle
int chargeNumber;
if (corsika::particles::IsNucleus(p.GetPID())) {
chargeNumber = p.GetNuclearZ();
} else {
chargeNumber = corsika::particles::GetChargeNumber(p.GetPID());
}
auto const* currentLogicalVolumeNode = p.GetNode();
auto magneticfield = currentLogicalVolumeNode->GetModelProperties().GetMagneticField(p.GetPosition());
auto k = chargeNumber * corsika::units::constants::cSquared * 1_eV / (line.GetV0().norm() * p.GetEnergy() * 1_V);
geometry::Vector<dimensionless_d> const directionBefore = line.GetV0().normalized();
geometry::Line lineWithoutB(currentPosition, velocity);
// determine direction of the particle after adding magnetic field
// assuming magnetic field does not change during movement
// First Movement // First Movement
auto position = currentPosition + velocity * min / 2; // assuming magnetic field does not change during movement
auto position = p.GetPosition() + directionBefore * Steplength / 2;
// Change of direction by magnetic field // Change of direction by magnetic field
geometry::Vector<dimensionless_d> const directionAfter = directionBefore + velocity.cross(magneticfield) * geometry::Vector<dimensionless_d> const directionAfter = directionBefore + directionBefore.cross(magneticfield) *
min * k; Steplength * k;
// Second Movement // Second Movement
position = position + directionAfter * velocity.norm() * min / 2; position = position + directionAfter * Steplength / 2;
if ((position - currentPosition).GetNorm() != 0_m) { auto distance = position - p.GetPosition();
geometry::Vector<dimensionless_d> const direction = (position - currentPosition).normalized();
velocity = direction * velocity.norm(); if(distance.norm() == 0_m) {
} // no velocity update for very small steps return std::make_tuple(line, position, directionAfter);
geometry::Line lineWithB(currentPosition, velocity); }
geometry::Line newLine(p.GetPosition(), distance.normalized() * line.GetV0().norm());
return std::make_tuple(geometry::Trajectory<geometry::Line>(lineWithoutB, min), return std::make_tuple(newLine, position, directionAfter);
geometry::Trajectory<geometry::Line>(lineWithB, min),
velocity.norm() * min, minIter->second);
} }
}; };
......
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