-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Momentum Diffusion #444
Momentum Diffusion #444
Changes from 6 commits
5e78fd9
c74771a
d333f7a
630bf17
3b5b90a
ce9ffae
834f69c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#ifndef CRPROPA_MOMENTUMDIFFUSION_H | ||
#define CRPROPA_MOMENTUMDIFFUSION_H | ||
|
||
#include <iostream> | ||
#include <vector> | ||
#include <cmath> | ||
#include <string> | ||
#include <cstdlib> | ||
#include <stdexcept> | ||
|
||
#include <crpropa/Module.h> | ||
#include <crpropa/Units.h> | ||
#include <crpropa/Random.h> | ||
|
||
#include "kiss/logger.h" | ||
|
||
namespace crpropa { | ||
|
||
/** | ||
* \addtogroup EnergyLosses | ||
* @{ | ||
*/ | ||
|
||
/** | ||
@class ConstantMomentumDiffusion | ||
* Simplest model for diffusion in momentum space | ||
*/ | ||
|
||
class ConstantMomentumDiffusion: public Module { | ||
|
||
private: | ||
double Dpp; // Diffusion coefficient | ||
double limit; // maximal fractional energy loss | ||
|
||
public: | ||
/** Constructor | ||
@param Dpp momentum diffusion coefficient | ||
*/ | ||
|
||
ConstantMomentumDiffusion(double Dpp); | ||
|
||
void process(Candidate *candidate) const; | ||
double calculateAScalar(double p) const; | ||
double calculateBScalar() const; | ||
|
||
void setLimit(double l); | ||
void setDpp(double Dpp); | ||
|
||
double getLimit() const; | ||
double getDpp() const; | ||
|
||
std::string getDescription() const; | ||
|
||
}; | ||
|
||
/** @}*/ | ||
|
||
}; //end namespace crpropa | ||
|
||
#endif // CRPROPA_MOMENTUMDIFFUSION_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#include "crpropa/module/MomentumDiffusion.h" | ||
|
||
using namespace crpropa; | ||
|
||
ConstantMomentumDiffusion::ConstantMomentumDiffusion(double Dpp) { | ||
setLimit(0.1); | ||
setDpp(Dpp); | ||
} | ||
|
||
void ConstantMomentumDiffusion::process(Candidate *c) const { | ||
double rig = c->current.getRigidity(); | ||
if (std::isinf(rig)) { | ||
return; // Only charged particles | ||
} | ||
|
||
double p = c->current.getEnergy()/c_light; // Note we use E=p/c (relativistic limit) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add spaces: |
||
double dt = c->getCurrentStep() / c_light; | ||
|
||
double eta = Random::instance().randNorm(); | ||
double domega = eta * sqrt(dt); | ||
|
||
double AScal = calculateAScalar(p); | ||
double BScal = calculateBScalar(); | ||
|
||
double dp = AScal * dt + BScal * domega; | ||
c->current.setEnergy((p + dp)*c_light); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add spaces between parenthesis and c_light. |
||
|
||
c->limitNextStep(limit * p / AScal * c_light); | ||
} | ||
|
||
double ConstantMomentumDiffusion::calculateAScalar(double p) const { | ||
double a = + 2./p * Dpp; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Follow CRPropa convention and add white spaces around |
||
return a; | ||
} | ||
|
||
double ConstantMomentumDiffusion::calculateBScalar() const { | ||
double b = sqrt(2 * Dpp); | ||
return b; | ||
} | ||
|
||
void ConstantMomentumDiffusion::setDpp(double d) { | ||
if (d < 0 ) | ||
throw std::runtime_error( | ||
"ConstantMomentumDiffusion: Dpp must be non-negative"); | ||
Dpp = d; | ||
} | ||
|
||
void ConstantMomentumDiffusion::setLimit(double l) { | ||
limit = l; | ||
} | ||
|
||
double ConstantMomentumDiffusion::getDpp() const { | ||
return Dpp; | ||
} | ||
|
||
double ConstantMomentumDiffusion::getLimit() const { | ||
return limit; | ||
} | ||
|
||
std::string ConstantMomentumDiffusion::getDescription() const { | ||
std::stringstream s; | ||
s << "limit: " << limit << "\n"; | ||
s << "Dpp: " << Dpp / (meter*meter/second) << " m^2/s"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add white spaces, following CRPropa's convention. |
||
|
||
return s.str(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# coding=utf-8 | ||
import sys | ||
|
||
try: | ||
import unittest | ||
except: | ||
print("***********************************************************") | ||
print("* WARNING!! Couldn't import python unittesting framework! *") | ||
print("* No python tests have been executed *") | ||
print("***********************************************************") | ||
sys.exit(0) | ||
|
||
try: | ||
import numpy as np | ||
except: | ||
print("***********************************************************") | ||
print("* WARNING!! Couldn't import numpy framework! *") | ||
print("* No python tests have been executed *") | ||
print("***********************************************************") | ||
sys.exit(-1) | ||
|
||
try: | ||
import crpropa | ||
from crpropa import nG, kpc, pc, GeV, TeV, PeV, c_light | ||
except Exception as e: | ||
print("*** CRPropa import failed") | ||
print(type(e), str(e)) | ||
sys.exit(-2) | ||
|
||
|
||
class MomentumDiffusion(unittest.TestCase): | ||
|
||
Dpp = 10 | ||
limit = 0.3 | ||
|
||
momDif = crpropa.ConstantMomentumDiffusion(Dpp) | ||
momDif.setLimit(limit) | ||
|
||
def test_Simple(self): | ||
self.assertEqual(self.momDif.getDpp(), self.Dpp) | ||
self.assertEqual(self.momDif.getLimit(), self.limit) | ||
|
||
def test_Helper(self): | ||
"""Test to check the calculation of the helper functions | ||
Dpp | ||
B | ||
A | ||
""" | ||
E = 10*TeV | ||
c = crpropa.Candidate(crpropa.nucleusId(1,1)) | ||
c.current.setEnergy(E) | ||
p = c.current.getEnergy() / c_light | ||
|
||
bscal = self.momDif.calculateBScalar() | ||
self.assertEqual(np.sqrt(2*self.Dpp), bscal) | ||
ascal = self.momDif.calculateAScalar(p, Dpp) | ||
self.assertAlmostEqual(2/p*self.Dpp, ascal) | ||
|
||
def test_NeutralParticle(self): | ||
E = 10*TeV | ||
c = crpropa.Candidate(crpropa.nucleusId(1,0)) | ||
c.current.setEnergy(E) | ||
c.setNextStep(10) | ||
self.momDif.process(c) | ||
|
||
self.assertEqual(c.current.getEnergy(), E) #acts only on charged particles | ||
self.assertEqual(c.getNextStep(), 10) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it make sense to allow the user to control the limit, as done in the other modules?