Commit 9798e856 authored by jannick.wolters's avatar jannick.wolters
Browse files

added scattering kernel and scatteringXS

parent f8b4ecb8
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
class Checkerboard : public ProblemBase class Checkerboard : public ProblemBase
{ {
private: private:
std::vector<Matrix> _scatteringXS; Vector _scatteringXS;
std::vector<double> _totalXS; Vector _totalXS;
Checkerboard() = delete; Checkerboard() = delete;
...@@ -17,8 +17,8 @@ class Checkerboard : public ProblemBase ...@@ -17,8 +17,8 @@ class Checkerboard : public ProblemBase
Checkerboard( Config* settings, Mesh* mesh ); Checkerboard( Config* settings, Mesh* mesh );
virtual ~Checkerboard(); virtual ~Checkerboard();
virtual std::vector<Matrix> GetScatteringXS( const double energy ); virtual VectorVector GetScatteringXS( const std::vector<double>& energies );
virtual std::vector<double> GetTotalXS( const double energy ); virtual VectorVector GetTotalXS( const std::vector<double>& energies );
virtual std::vector<double> GetStoppingPower( const std::vector<double>& energies ); virtual std::vector<double> GetStoppingPower( const std::vector<double>& energies );
virtual VectorVector SetupIC(); virtual VectorVector SetupIC();
}; };
......
...@@ -19,8 +19,8 @@ class ElectronRT : public ProblemBase ...@@ -19,8 +19,8 @@ class ElectronRT : public ProblemBase
ElectronRT( Config* settings, Mesh* mesh ); ElectronRT( Config* settings, Mesh* mesh );
virtual ~ElectronRT(); virtual ~ElectronRT();
virtual std::vector<Matrix> GetScatteringXS( const double energy ); virtual VectorVector GetScatteringXS( const std::vector<double>& energies );
virtual std::vector<double> GetTotalXS( const double energy ); virtual VectorVector GetTotalXS( const std::vector<double>& energies );
virtual std::vector<double> GetStoppingPower( const std::vector<double>& energies ); virtual std::vector<double> GetStoppingPower( const std::vector<double>& energies );
virtual VectorVector SetupIC(); virtual VectorVector SetupIC();
}; };
......
...@@ -12,8 +12,8 @@ class LineSource : public ProblemBase ...@@ -12,8 +12,8 @@ class LineSource : public ProblemBase
LineSource( Config* settings, Mesh* mesh ); LineSource( Config* settings, Mesh* mesh );
virtual ~LineSource(); virtual ~LineSource();
virtual std::vector<Matrix> GetScatteringXS( const double energy ); virtual VectorVector GetScatteringXS( const std::vector<double>& energies );
virtual std::vector<double> GetTotalXS( const double energy ); virtual VectorVector GetTotalXS( const std::vector<double>& energies );
virtual std::vector<double> GetStoppingPower( const std::vector<double>& energies ); virtual std::vector<double> GetStoppingPower( const std::vector<double>& energies );
virtual VectorVector SetupIC(); virtual VectorVector SetupIC();
}; };
......
...@@ -14,8 +14,6 @@ class ProblemBase ...@@ -14,8 +14,6 @@ class ProblemBase
Mesh* _mesh; Mesh* _mesh;
Physics* _physics; Physics* _physics;
std::vector<double> _totalXS;
Matrix _scatteringXS;
std::vector<double> _density; std::vector<double> _density;
std::vector<double> _stoppingPower; std::vector<double> _stoppingPower;
...@@ -24,24 +22,20 @@ class ProblemBase ...@@ -24,24 +22,20 @@ class ProblemBase
public: public:
/** /**
* @brief GetScatteringXS gives back vector of vectors of scattering cross sections for materials defined by density and energies in vector energy * @brief GetScatteringXS gives back vector of vectors of scattering cross sections for materials defined by density and energies in vector energy
* @param energies is vector with energies * @param energy is the energy the cross section is queried for
* @param density is vector with patient densities (at different spatial cells)
* @param Omega are scattering angles
*/ */
virtual std::vector<Matrix> GetScatteringXS( const double energy ) = 0; virtual VectorVector GetScatteringXS( const std::vector<double>& energies ) = 0;
/** /**
* @brief GetTotalXS gives back vector of vectors of total cross sections for materials defined by density and energies in vector energy * @brief GetTotalXS gives back vector of vectors of total cross sections for materials defined by density and energies in vector energy
* @param energies is vector with energies * @param energy is the energy the cross section is queried for
* @param density is vector with patient densities (at different spatial cells) * @param density is vector with patient densities (at different spatial cells)
*/ */
virtual std::vector<double> GetTotalXS( const double energy ) = 0; virtual VectorVector GetTotalXS( const std::vector<double>& energies ) = 0;
/** /**
* @brief GetStoppingPower gives back vector of vectors of stopping powers for materials defined by density and energies in vector energy * @brief GetStoppingPower gives back vector of vectors of stopping powers for materials defined by density and energies in vector energy
* @param energies is vector with energies * @param energies is vector with energies
* @param density is vector with patient densities (at different spatial cells)
* @param sH2O is vector of stopping powers in water
*/ */
virtual std::vector<double> GetStoppingPower( const std::vector<double>& energies ) = 0; virtual std::vector<double> GetStoppingPower( const std::vector<double>& energies ) = 0;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
class SNSolver : public Solver class SNSolver : public Solver
{ {
private:
public: public:
/** /**
* @brief SNSolver constructor * @brief SNSolver constructor
......
...@@ -24,6 +24,9 @@ class Solver ...@@ -24,6 +24,9 @@ class Solver
std::vector<std::vector<unsigned>> _neighbors; // edge normals multiplied by edge length, dim(_neighbors) = (_NCells,nEdgesPerCell) std::vector<std::vector<unsigned>> _neighbors; // edge normals multiplied by edge length, dim(_neighbors) = (_NCells,nEdgesPerCell)
std::vector<double> _density; // patient density, dim(_density) = _nCells std::vector<double> _density; // patient density, dim(_density) = _nCells
std::vector<double> _s; // stopping power, dim(_s) = _nTimeSteps std::vector<double> _s; // stopping power, dim(_s) = _nTimeSteps
VectorVector _sigmaS; // scattering cross section for all energies
VectorVector _sigmaT; // total cross section for all energies
Matrix _scatteringKernel; // scattering kernel for the quadrature
VectorVector _quadPoints; // quadrature points, dim(_quadPoints) = (_nTimeSteps,spatialDim) VectorVector _quadPoints; // quadrature points, dim(_quadPoints) = (_nTimeSteps,spatialDim)
Vector _weights; // quadrature weights, dim(_weights) = (_NCells) Vector _weights; // quadrature weights, dim(_weights) = (_NCells)
std::vector<bool> _boundaryCells; // boundary type for all cells, dim(_boundary) = (_NCells) std::vector<bool> _boundaryCells; // boundary type for all cells, dim(_boundary) = (_NCells)
...@@ -39,6 +42,7 @@ class Solver ...@@ -39,6 +42,7 @@ class Solver
* @param cfl is cfl number * @param cfl is cfl number
*/ */
double ComputeTimeStep( double cfl ) const; double ComputeTimeStep( double cfl ) const;
Matrix ComputeScatteringKernel() const;
public: public:
/** /**
......
...@@ -12,4 +12,4 @@ PROBLEM = CHECKERBOARD ...@@ -12,4 +12,4 @@ PROBLEM = CHECKERBOARD
% ---- Boundary Conditions ---- % ---- Boundary Conditions ----
BC_DIRICHLET = ( void ) BC_DIRICHLET = ( void )
QUAD_TYPE = LEBEDEV QUAD_TYPE = LEBEDEV
QUAD_ORDER = 19 QUAD_ORDER = 35
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Checkerboard::Checkerboard( Config* settings, Mesh* mesh ) : ProblemBase( settings, mesh ) { Checkerboard::Checkerboard( Config* settings, Mesh* mesh ) : ProblemBase( settings, mesh ) {
_physics = nullptr; _physics = nullptr;
_scatteringXS.resize( _mesh->GetNumCells(), Matrix( _settings->GetNQuadPoints(), _settings->GetNQuadPoints(), 0.0 ) ); // @TODO _scatteringXS.resize( _mesh->GetNumCells(), 1.0 );
_totalXS.resize( _mesh->GetNumCells(), 1.0 ); _totalXS.resize( _mesh->GetNumCells(), 1.0 );
auto cellMids = _mesh->GetCellMidPoints(); auto cellMids = _mesh->GetCellMidPoints();
for( unsigned j = 0; j < cellMids.size(); ++j ) { for( unsigned j = 0; j < cellMids.size(); ++j ) {
...@@ -15,9 +15,9 @@ Checkerboard::Checkerboard( Config* settings, Mesh* mesh ) : ProblemBase( settin ...@@ -15,9 +15,9 @@ Checkerboard::Checkerboard( Config* settings, Mesh* mesh ) : ProblemBase( settin
Checkerboard::~Checkerboard() {} Checkerboard::~Checkerboard() {}
std::vector<Matrix> Checkerboard::GetScatteringXS( const double energy ) { return _scatteringXS; } VectorVector Checkerboard::GetScatteringXS( const std::vector<double>& energies ) { return VectorVector( energies.size(), _scatteringXS ); }
std::vector<double> Checkerboard::GetTotalXS( const double energy ) { return _totalXS; } VectorVector Checkerboard::GetTotalXS( const std::vector<double>& energies ) { return VectorVector( energies.size(), _totalXS ); }
std::vector<double> Checkerboard::GetStoppingPower( const std::vector<double>& energies ) { std::vector<double> Checkerboard::GetStoppingPower( const std::vector<double>& energies ) {
// @TODO // @TODO
......
...@@ -7,14 +7,14 @@ ElectronRT::ElectronRT( Config* settings, Mesh* mesh ) : ProblemBase( settings, ...@@ -7,14 +7,14 @@ ElectronRT::ElectronRT( Config* settings, Mesh* mesh ) : ProblemBase( settings,
ElectronRT::~ElectronRT() {} ElectronRT::~ElectronRT() {}
std::vector<Matrix> ElectronRT::GetScatteringXS( const double energy ) { VectorVector ElectronRT::GetScatteringXS( const std::vector<double>& energies ) {
// @TODO // @TODO
return std::vector<Matrix>( _mesh->GetNumCells(), Matrix( _settings->GetNQuadPoints(), _settings->GetNQuadPoints(), 0.0 ) ); return VectorVector( energies.size(), Vector( _mesh->GetNumCells(), 0.0 ) );
} }
std::vector<double> ElectronRT::GetTotalXS( const double energy ) { VectorVector ElectronRT::GetTotalXS( const std::vector<double>& energies ) {
// @TODO // @TODO
return std::vector<double>( _mesh->GetNumCells(), 0.0 ); return VectorVector( energies.size(), Vector( _mesh->GetNumCells(), 0.0 ) );
} }
std::vector<double> ElectronRT::GetStoppingPower( const std::vector<double>& energies ) { std::vector<double> ElectronRT::GetStoppingPower( const std::vector<double>& energies ) {
......
...@@ -4,11 +4,13 @@ LineSource::LineSource( Config* settings, Mesh* mesh ) : ProblemBase( settings, ...@@ -4,11 +4,13 @@ LineSource::LineSource( Config* settings, Mesh* mesh ) : ProblemBase( settings,
LineSource::~LineSource(){}; LineSource::~LineSource(){};
std::vector<Matrix> LineSource::GetScatteringXS( const double energy ) { VectorVector LineSource::GetScatteringXS( const std::vector<double>& energies ) {
return std::vector<Matrix>( _mesh->GetNumCells(), Matrix( _settings->GetNQuadPoints(), _settings->GetNQuadPoints(), 0.0 ) ); return VectorVector( energies.size(), Vector( _mesh->GetNumCells(), 0.0 ) );
} }
std::vector<double> LineSource::GetTotalXS( const double energy ) { return std::vector<double>( _mesh->GetNumCells(), 0.0 ); } VectorVector LineSource::GetTotalXS( const std::vector<double>& energies ) {
return VectorVector( energies.size(), Vector( _mesh->GetNumCells(), 0.0 ) );
}
std::vector<double> LineSource::GetStoppingPower( const std::vector<double>& energies ) { std::vector<double> LineSource::GetStoppingPower( const std::vector<double>& energies ) {
// @TODO // @TODO
......
...@@ -14,8 +14,6 @@ void SNSolver::Solve() { ...@@ -14,8 +14,6 @@ void SNSolver::Solve() {
// loop over energies (pseudo-time) // loop over energies (pseudo-time)
for( unsigned n = 0; n < _nEnergies; ++n ) { for( unsigned n = 0; n < _nEnergies; ++n ) {
auto sigmaT = _problem->GetTotalXS( _energies[n] );
auto sigmaS = _problem->GetScatteringXS( _energies[n] );
// loop over all spatial cells // loop over all spatial cells
for( unsigned j = 0; j < _nCells; ++j ) { for( unsigned j = 0; j < _nCells; ++j ) {
if( _boundaryCells[j] ) continue; if( _boundaryCells[j] ) continue;
...@@ -28,10 +26,10 @@ void SNSolver::Solve() { ...@@ -28,10 +26,10 @@ void SNSolver::Solve() {
psiNew[j][k] -= _g->Flux( _quadPoints[k], _psi[j][k], _psi[_neighbors[j][l]][k], _normals[j][l] ); psiNew[j][k] -= _g->Flux( _quadPoints[k], _psi[j][k], _psi[_neighbors[j][l]][k], _normals[j][l] );
} }
// time update angular flux with numerical flux and total scattering cross section // time update angular flux with numerical flux and total scattering cross section
psiNew[j][k] = _psi[j][k] + ( _dE / _areas[j] ) * psiNew[j][k] - _dE * sigmaT[j] * _psi[j][k]; psiNew[j][k] = _psi[j][k] + ( _dE / _areas[j] ) * psiNew[j][k] - _dE * _sigmaT[n][j] * _psi[j][k];
} }
// compute scattering effects // compute scattering effects
psiNew[j] += sigmaS[j] * _psi[j] * _weights; // multiply scattering matrix with psi psiNew[j] += _scatteringKernel * _sigmaS[n][j] * _psi[j] * _weights; // multiply scattering matrix with psi
} }
_psi = psiNew; _psi = psiNew;
if( rank == 0 ) log->info( "{:03.8f} {:01.5e}", _energies[n], 0.0 ); if( rank == 0 ) log->info( "{:03.8f} {:01.5e}", _energies[n], 0.0 );
......
...@@ -21,16 +21,19 @@ Solver::Solver( Config* settings ) : _settings( settings ) { ...@@ -21,16 +21,19 @@ Solver::Solver( Config* settings ) : _settings( settings ) {
_weights = q->GetWeights(); _weights = q->GetWeights();
_nq = q->GetNq(); _nq = q->GetNq();
_settings->SetNQuadPoints( _nq ); _settings->SetNQuadPoints( _nq );
_scatteringKernel = ComputeScatteringKernel();
// set time step // set time step
_dE = ComputeTimeStep( settings->GetCFL() ); _dE = ComputeTimeStep( settings->GetCFL() );
_nEnergies = unsigned( settings->GetTEnd() / _dE ); _nEnergies = unsigned( settings->GetTEnd() / _dE );
for( unsigned i = 0; i < _nEnergies; ++i ) _energies.push_back( i * _dE ); for( unsigned i = 0; i < _nEnergies; ++i ) _energies.push_back( ( i + 1 ) * _dE );
// setup problem // setup problem
_problem = ProblemBase::Create( _settings, _mesh ); _problem = ProblemBase::Create( _settings, _mesh );
_psi = _problem->SetupIC(); _psi = _problem->SetupIC();
_s = _problem->GetStoppingPower( _energies ); _s = _problem->GetStoppingPower( _energies );
_sigmaT = _problem->GetTotalXS( _energies );
_sigmaS = _problem->GetScatteringXS( _energies );
// setup numerical flux // setup numerical flux
_g = NumericalFlux::Create( settings ); _g = NumericalFlux::Create( settings );
...@@ -50,4 +53,25 @@ double Solver::ComputeTimeStep( double cfl ) const { ...@@ -50,4 +53,25 @@ double Solver::ComputeTimeStep( double cfl ) const {
return cfl * maxEdge; return cfl * maxEdge;
} }
Matrix Solver::ComputeScatteringKernel() const {
Matrix kernel( _nq, _nq, 0.0 );
for( unsigned i = 0; i < _nq; ++i ) {
auto omega = _quadPoints[i];
for( unsigned j = 0; j < _nq; ++j ) {
auto omegaprime = _quadPoints[j];
double eps = 4.0 / _nq;
auto x = ( 1 - dot( omega, omegaprime ) );
double val = ( _weights[j] * 1.0 / eps * exp( -( x * x ) / ( eps * eps ) ) );
if( val < 1e-8 )
kernel( i, j ) = 0.0;
else
kernel( i, j ) = val;
}
column( kernel, i ) /= sum( column( kernel, i ) );
column( kernel, i ) /= _weights;
}
return kernel;
}
Solver* Solver::Create( Config* settings ) { return new SNSolver( settings ); } Solver* Solver::Create( Config* settings ) { return new SNSolver( settings ); }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment