LCOV - code coverage report
Current view: top level - src/module - CandidateSplitting.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 89.8 % 59 53
Test Date: 2026-06-18 09:49:19 Functions: 90.9 % 11 10

            Line data    Source code
       1              : #include "crpropa/module/CandidateSplitting.h"
       2              : 
       3              : namespace crpropa {
       4              : 
       5            0 : CandidateSplitting::CandidateSplitting() {
       6              :         // no particle splitting if EnergyBins and NSplit are not specified
       7            0 :         setNsplit(0);
       8            0 :         setMinimalWeight(1.);
       9            0 : }
      10              : 
      11            3 : CandidateSplitting::CandidateSplitting(int nSplit, double Emin, double Emax,  double nBins, double minWeight, bool log) {
      12            3 :         setNsplit(nSplit);
      13            3 :         setEnergyBins(Emin, Emax, nBins, log);
      14            3 :         setMinimalWeight(minWeight);
      15            3 : }
      16              : 
      17            1 : CandidateSplitting::CandidateSplitting(double spectralIndex, double Emin, int nBins)  {
      18              :         // to use with Diffusive Shock Acceleration
      19            1 :         if (spectralIndex > 0){
      20              :                 throw std::runtime_error(
      21            0 :                                 "CandidateSplitting: spectralIndex > 0 !"); 
      22              :         }
      23              : 
      24            1 :         setNsplit(2); // always split in 2, calculate bins in energy for given spectrum:
      25            1 :         double dE = pow(1. / 2, 1. / (spectralIndex + 1)); 
      26            1 :         setEnergyBinsDSA(Emin, dE, nBins);
      27            1 :         setMinimalWeight(1. / pow(2, nBins));
      28            1 : }
      29              : 
      30            6 : void CandidateSplitting::process(Candidate *c) const {
      31            6 :         double currE = c->current.getEnergy(); 
      32            6 :         double prevE = c->previous.getEnergy();
      33              : 
      34            6 :         if (c->getWeight() <= minWeight){
      35              :                 // minimal weight reached, no splitting
      36              :                 return;
      37              :         }
      38            5 :         if (currE < Ebins[0] || nSplit == 0 ){
      39              :                 // current energy is smaller than first bin -> no splitting
      40              :                 // or, number of splits = 0
      41              :                 return;
      42              :         }
      43            4 :         for (size_t i = 0; i < Ebins.size(); ++i){
      44              :                 
      45            4 :                 if( prevE < Ebins[i] ){
      46              :                         // previous energy is in energy bin [i-1, i]
      47            3 :                         if(currE < Ebins[i]){
      48              :                                 //assuming that dE greater than 0, prevE and E in same energy bin -> no splitting
      49              :                                 return;
      50              :                         }
      51              :                         // current energy is in energy bin [i,i+1] or higher -> particle splitting for each crossing
      52            4 :                         for (size_t j = i; j < Ebins.size(); ++j ){
      53              : 
      54              :                                 // adapted from Acceleration Module:
      55            4 :                                 c->updateWeight(1. / nSplit); // * 1/n_split
      56              : 
      57            8 :                                 for (int i = 1; i < nSplit; i++) {
      58              :                                 
      59            4 :                                         ref_ptr<Candidate> new_candidate = c->clone(false);
      60            4 :                                         new_candidate->parent = c;
      61            4 :                                         new_candidate->previous.setEnergy(currE); // so that new candidate is not split again in next step!
      62              :                                         c->addSecondary(new_candidate);
      63              :                                 }
      64            4 :                                 if (j < Ebins.size()-1 && currE < Ebins[j+1]){
      65              :                                         // candidate is in energy bin [j, j+1] -> no further splitting
      66              :                                         return;
      67              :                                 }
      68              :                         }
      69              :                         return;
      70              :                 }
      71              :         }
      72              : }
      73              : 
      74            3 : void CandidateSplitting::setEnergyBins(double Emin, double Emax, double nBins, bool log) {
      75            3 :         Ebins.resize(0);
      76            3 :         if (Emin > Emax){
      77              :                 throw std::runtime_error(
      78            0 :                                 "CandidateSplitting: Emin > Emax!");
      79              :         }
      80            3 :         double dE = (Emax-Emin)/nBins;
      81           14 :         for (size_t i = 0; i < nBins; ++i) {
      82           11 :                 if (log == true) {
      83            4 :                         Ebins.push_back(Emin * pow(Emax / Emin, i / (nBins - 1.0)));
      84              :                 } else {
      85            7 :                         Ebins.push_back(Emin + i * dE);
      86              :                 }
      87              :         }
      88            3 : }
      89              : 
      90            1 : void CandidateSplitting::setEnergyBinsDSA(double Emin, double dE, int n) {
      91            1 :         Ebins.resize(0);
      92            5 :         for (size_t i = 1; i < n + 1; ++i) {
      93            4 :                 Ebins.push_back(Emin * pow(dE, i));
      94              :         }
      95            1 : }
      96              : 
      97            6 : const std::vector<double>& CandidateSplitting::getEnergyBins() const {
      98            6 :         return Ebins;
      99              : }
     100              : 
     101            4 : void CandidateSplitting::setNsplit(int n) {
     102            4 :         nSplit = n;
     103            4 : }
     104              : 
     105            4 : void CandidateSplitting::setMinimalWeight(double w) {
     106            4 :         minWeight = w;
     107            4 : }
     108              : 
     109            1 : int CandidateSplitting::getNsplit() const {
     110            1 :         return nSplit;
     111              : }
     112              : 
     113            1 : double CandidateSplitting::getMinimalWeight() const {
     114            1 :         return minWeight;
     115              : }
     116              : 
     117              : } // end namespace crpropa
     118              : 
        

Generated by: LCOV version 2.0-1