Commit 57a22bce authored by steffen.schotthoefer's avatar steffen.schotthoefer
Browse files

PN Runs, needs testing

parent b8ff24fb
......@@ -66,6 +66,7 @@ class Mesh
const std::vector<BOUNDARY_TYPE>& GetBoundaryTypes() const;
double GetDistanceToOrigin( unsigned idx_cell ) const;
/**
* @brief ComputeSlopes calculates the slope in every cell into x and y direction
* @param nq is number of quadrature points
......
......@@ -44,6 +44,17 @@ class NumericalFlux
const Vector&,
const Vector& n,
Vector& resultFlux ) const = 0;
virtual void FluxVanLeer( const Matrix& Ax,
const Matrix& AxAbs,
const Matrix& Ay,
const Matrix& AyAbs,
const Matrix& Az,
const Matrix& AzAbs,
const Vector& psiL,
const Vector& psiR,
const Vector& n,
Vector& resultFlux ) const = 0;
};
#endif // NUMERICALFLUX_H
......@@ -25,12 +25,13 @@ class PNSolver : public Solver
*/
void Save() const override;
void Save( int currEnergy ) const;
protected:
// moment orders for P_N
unsigned _nTotalEntries; // total number of equations in the system
VectorVector _sigmaA; // absorbtion coefficient for all energies
// System Matrix for x, y and z flux
// ==> not needed after computation of A+ and A- ==> maybe safe only temporarly and remove as member?
SymMatrix _Ax;
......@@ -40,10 +41,13 @@ class PNSolver : public Solver
// Upwinding Matrices
Matrix _AxPlus;
Matrix _AxMinus;
Matrix _AxAbs;
Matrix _AyPlus;
Matrix _AyMinus;
Matrix _AyAbs;
Matrix _AzPlus;
Matrix _AzMinus;
Matrix _AzAbs;
Vector _scatterMatDiag; // diagonal of the scattering matrix (its a diagonal matrix by construction)
......@@ -64,8 +68,19 @@ class PNSolver : public Solver
int Sgn( int k ) const;
int kPlus( int k ) const;
int kMinus( int k ) const;
/*! @brief : computes the global index of the moment corresponding to basis function (l,k)
* @param : degree l, it must hold: 0 <= l <=_nq
* @param : order k, it must hold: -l <=k <= l
* @returns : global index
*/
int GlobalIndex( int l, int k ) const;
/*! @brief : Checks, if index invariant for global index holds
* @returns : True, if invariant holds, else false
*/
bool CheckIndex( int l, int k ) const;
// function for computing and setting up system matrices
void ComputeSystemMatrices();
// function for computing and setting up flux matrices for upwinding
......
......@@ -25,6 +25,7 @@ class SNSolver : public Solver
* @brief Output solution to VTK file
*/
virtual void Save() const;
virtual void Save( int currEnergy ) const;
};
#endif // SNSOLVER_H
......@@ -33,6 +33,8 @@ class Solver
VectorVector _quadPoints; // quadrature points, dim(_quadPoints) = (_nTimeSteps,spatialDim)
Vector _weights; // quadrature weights, dim(_weights) = (_NCells)
std::vector<BOUNDARY_TYPE> _boundaryCells; // boundary type for all cells, dim(_boundary) = (_NCells)
std::vector<double> _solverOutput; // PROTOTYPE: Outputfield for solver
// we will have to add a further dimension for quadPoints and weights once we start with multilevel SN
NumericalFlux* _g; // numerical flux function
......@@ -69,6 +71,8 @@ class Solver
* @brief Output solution to VTK file
*/
virtual void Save() const = 0;
virtual void Save( int currEnergy ) const = 0;
};
#endif // SOLVER_H
......@@ -48,6 +48,32 @@ class UpwindFlux : public NumericalFlux
const Vector& psiR,
const Vector& n,
Vector& resultFlux ) const override;
/**
* @brief Flux : Computes <VanLeer> upwinding scheme for given flux jacobians of the PN Solver at a given edge and stores it in
* resultFlux
* @param AxPlus : Positive part of the flux jacobian in x direction
* @param AxMinus : Negative part of the flux jacobian in x direction
* @param AyPlus : Positive part of the flux jacobian in y direction
* @param AyMinus : Negative part of the flux jacobian in y direction
* @param AzPlus : Positive part of the flux jacobian in z direction
* @param AzMinus : Negative part of the flux jacobian in z direction
* @param psiL : Solution state of left hand side control volume
* @param psiR : Solution state of right hand side control volume
* @param n : Normal vector at the edge between left and right control volume
* @param resultFlux: Vector with resulting flux.
* @return : void
*/
void FluxVanLeer( const Matrix& Ax,
const Matrix& AxAbs,
const Matrix& Ay,
const Matrix& AyAbs,
const Matrix& Az,
const Matrix& AzAbs,
const Vector& psiL,
const Vector& psiR,
const Vector& n,
Vector& resultFlux ) const override;
};
#endif // UPWINDFLUX_H
......@@ -20,7 +20,7 @@ PROBLEM = LINESOURCE
% Solver type
SOLVER = PN_SOLVER
% CFL number
CFL_NUMBER = 0.4
CFL_NUMBER = 0.3
% Final time for simulation
TIME_FINAL = 0.3
......@@ -33,4 +33,4 @@ BC_DIRICHLET = ( void )
% Quadrature Type
QUAD_TYPE = MONTE_CARLO
% Quadrature Order
QUAD_ORDER = 2
QUAD_ORDER = 1
......@@ -33,7 +33,7 @@ void Mesh::ComputeConnectivity() {
sortedBoundaries.push_back( _boundaries[i].second );
std::sort( sortedBoundaries[i].begin(), sortedBoundaries[i].end() );
}
//#pragma omp parallel for
#pragma omp parallel for
for( unsigned i = mpiCellStart; i < mpiCellEnd; ++i ) {
std::vector<unsigned>* cellsI = &sortedCells[i];
for( unsigned j = 0; j < _numCells; ++j ) {
......@@ -333,3 +333,11 @@ const std::vector<unsigned>& Mesh::GetPartitionIDs() const { return _colors; }
const std::vector<std::vector<unsigned>>& Mesh::GetNeighbours() const { return _cellNeighbors; }
const std::vector<std::vector<Vector>>& Mesh::GetNormals() const { return _cellNormals; }
const std::vector<BOUNDARY_TYPE>& Mesh::GetBoundaryTypes() const { return _cellBoundaryTypes; }
double Mesh::GetDistanceToOrigin( unsigned idx_cell ) const {
double distance = 0.0;
for( unsigned idx_dim = 0; idx_dim < _dim; idx_dim++ ) {
distance += _cellMidPoints[idx_cell][idx_dim] * _cellMidPoints[idx_cell][idx_dim];
}
return sqrt( distance );
}
......@@ -12,7 +12,8 @@ PNSolver::PNSolver( Config* settings ) : Solver( settings ) {
_sigmaA = VectorVector( _nEnergies, Vector( _nCells, 0 ) ); // Get rid of this extra vektor!
for( unsigned n = 0; n < _nEnergies; n++ ) {
for( unsigned j = 0; j < _nCells; j++ ) {
_sigmaA[n][j] = _sigmaT[n][j] - _sigmaS[n][j];
_sigmaA[n][j] = 0; //_sigmaT[n][j] - _sigmaS[n][j];
_sigmaS[n][j] = 1;
}
}
......@@ -23,24 +24,39 @@ PNSolver::PNSolver( Config* settings ) : Solver( settings ) {
_AxPlus = Matrix( _nTotalEntries, _nTotalEntries, 0 );
_AxMinus = Matrix( _nTotalEntries, _nTotalEntries, 0 );
_AxAbs = Matrix( _nTotalEntries, _nTotalEntries, 0 );
_AyPlus = Matrix( _nTotalEntries, _nTotalEntries, 0 );
_AyMinus = Matrix( _nTotalEntries, _nTotalEntries, 0 );
_AyAbs = Matrix( _nTotalEntries, _nTotalEntries, 0 );
_AzPlus = Matrix( _nTotalEntries, _nTotalEntries, 0 );
_AzMinus = Matrix( _nTotalEntries, _nTotalEntries, 0 );
_AzAbs = Matrix( _nTotalEntries, _nTotalEntries, 0 );
// Initialize Scatter Matrix
_scatterMatDiag = Vector( _nq, 0 );
_scatterMatDiag = Vector( _nTotalEntries, 0 );
// Fill System Matrices
ComputeSystemMatrices();
std::cout << "System Matrix Set UP!" << std::endl;
// Compute Decomposition in positive and negative (eigenvalue) parts of flux jacobians
ComputeFluxComponents();
std::cout << "_Ax :\n" << _Ax << "\n "; // _AxP \n" << _AxPlus << "\n _AxM \n" << _AxMinus << "\n";
std::cout << "_Ay :\n" << _Ay << "\n "; //_AyP \n" << _AyPlus << "\n _AyM \n" << _AyMinus << "\n";
std::cout << "_Az :\n" << _Az << "\n "; //_AzP \n" << _AzPlus << "\n _AzM \n" << _AzMinus << "\n";
std::cout << "_AxA :\n" << _AxAbs << "\n "; // _AxP \n" << _AxPlus << "\n _AxM \n" << _AxMinus << "\n";
std::cout << "_AyA :\n" << _AyAbs << "\n "; //_AyP \n" << _AyPlus << "\n _AyM \n" << _AyMinus << "\n";
std::cout << "_AzA :\n" << _AzAbs << "\n ";
std::cout << "_AxA :\n" << _AxPlus - _AxMinus << "\n "; // _AxP \n" << _AxPlus << "\n _AxM \n" << _AxMinus << "\n";
std::cout << "_AyA :\n" << _AyPlus - _AyMinus << "\n "; //_AyP \n" << _AyPlus << "\n _AyM \n" << _AyMinus << "\n";
std::cout << "_AzA :\n" << _AzPlus - _AzMinus << "\n ";
// Compute diagonal of the scatter matrix (it's a diagonal matrix)
ComputeScatterMatrix();
std::cout << "scatterMatrix : " << _scatterMatDiag << "\n";
}
double PNSolver::CTilde( int l, int k ) const {
......@@ -103,6 +119,13 @@ int PNSolver::GlobalIndex( int l, int k ) const {
return numIndicesPrevLevel + prevIndicesThisLevel;
}
bool PNSolver::CheckIndex( int l, int k ) const {
if( l >= 0 && l <= int( _nq ) ) {
if( k >= -l && k <= l ) return true;
}
return false;
}
int PNSolver::Sgn( int k ) const {
if( k >= 0 )
return 1;
......@@ -111,78 +134,86 @@ int PNSolver::Sgn( int k ) const {
}
void PNSolver::ComputeSystemMatrices() {
int j = 0;
unsigned i = 0;
int idx_col = 0;
unsigned idx_row = 0;
// loop over columns of A
for( int idx_lOrder = 0; idx_lOrder <= int( _nq ); idx_lOrder++ ) { // index of legendre polynom
for( int idx_kOrder = -idx_lOrder; idx_kOrder <= idx_lOrder; idx_kOrder++ ) { // second index of legendre function
i = unsigned( GlobalIndex( idx_lOrder, idx_kOrder ) );
idx_row = unsigned( GlobalIndex( idx_lOrder, idx_kOrder ) );
// flux matrix in direction x
if( idx_kOrder != -1 ) {
j = GlobalIndex( idx_lOrder - 1, kMinus( idx_kOrder ) );
if( j >= 0 && j < int( _nTotalEntries ) ) {
_Ax( i, unsigned( j ) ) = 0.5 * CTilde( idx_lOrder - 1, std::abs( idx_kOrder ) - 1 );
{
if( idx_kOrder != -1 ) {
if( CheckIndex( idx_lOrder - 1, kMinus( idx_kOrder ) ) ) {
idx_col = GlobalIndex( idx_lOrder - 1, kMinus( idx_kOrder ) );
_Ax( idx_row, unsigned( idx_col ) ) = 0.5 * CTilde( idx_lOrder - 1, std::abs( idx_kOrder ) - 1 );
}
if( CheckIndex( idx_lOrder + 1, kMinus( idx_kOrder ) ) ) {
idx_col = GlobalIndex( idx_lOrder + 1, kMinus( idx_kOrder ) );
_Ax( idx_row, unsigned( idx_col ) ) = -0.5 * DTilde( idx_lOrder + 1, std::abs( idx_kOrder ) - 1 );
}
}
j = GlobalIndex( idx_lOrder + 1, kMinus( idx_kOrder ) );
if( j >= 0 && j < int( _nTotalEntries ) ) {
_Ax( i, unsigned( j ) ) = -0.5 * DTilde( idx_lOrder + 1, std::abs( idx_kOrder ) - 1 );
if( CheckIndex( idx_lOrder - 1, kPlus( idx_kOrder ) ) ) {
idx_col = GlobalIndex( idx_lOrder - 1, kPlus( idx_kOrder ) );
_Ax( idx_row, unsigned( idx_col ) ) = -0.5 * ETilde( idx_lOrder - 1, std::abs( idx_kOrder ) + 1 );
}
}
j = GlobalIndex( idx_lOrder - 1, kPlus( idx_kOrder ) );
if( j >= 0 && j < int( _nTotalEntries ) ) {
_Ax( i, unsigned( j ) ) = -0.5 * ETilde( idx_lOrder - 1, std::abs( idx_kOrder ) + 1 );
}
j = GlobalIndex( idx_lOrder + 1, kPlus( idx_kOrder ) );
if( j >= 0 && j < int( _nTotalEntries ) ) {
_Ax( i, unsigned( j ) ) = 0.5 * FTilde( idx_lOrder + 1, std::abs( idx_kOrder ) + 1 );
if( CheckIndex( idx_lOrder + 1, kPlus( idx_kOrder ) ) ) {
idx_col = GlobalIndex( idx_lOrder + 1, kPlus( idx_kOrder ) );
_Ax( idx_row, unsigned( idx_col ) ) = 0.5 * FTilde( idx_lOrder + 1, std::abs( idx_kOrder ) + 1 );
}
}
//
// flux matrix in direction y
if( idx_kOrder != 1 ) {
j = GlobalIndex( idx_lOrder - 1, -kMinus( idx_kOrder ) );
if( j >= 0 && j < int( _nTotalEntries ) ) {
_Ay( i, unsigned( j ) ) = -0.5 * Sgn( idx_kOrder ) * CTilde( idx_lOrder - 1, std::abs( idx_kOrder ) - 1 );
{
if( idx_kOrder != 1 ) {
if( CheckIndex( idx_lOrder - 1, -kMinus( idx_kOrder ) ) ) {
idx_col = GlobalIndex( idx_lOrder - 1, -kMinus( idx_kOrder ) );
_Ay( idx_row, unsigned( idx_col ) ) = -0.5 * Sgn( idx_kOrder ) * CTilde( idx_lOrder - 1, std::abs( idx_kOrder ) - 1 );
}
if( CheckIndex( idx_lOrder + 1, -kMinus( idx_kOrder ) ) ) {
idx_col = GlobalIndex( idx_lOrder + 1, -kMinus( idx_kOrder ) );
_Ay( idx_row, unsigned( idx_col ) ) = 0.5 * Sgn( idx_kOrder ) * DTilde( idx_lOrder + 1, std::abs( idx_kOrder ) - 1 );
}
}
j = GlobalIndex( idx_lOrder + 1, -kMinus( idx_kOrder ) );
if( j >= 0 && j < int( _nTotalEntries ) ) {
_Ay( i, unsigned( j ) ) = 0.5 * Sgn( idx_kOrder ) * DTilde( idx_lOrder + 1, std::abs( idx_kOrder ) - 1 );
if( CheckIndex( idx_lOrder - 1, -kPlus( idx_kOrder ) ) ) {
idx_col = GlobalIndex( idx_lOrder - 1, -kPlus( idx_kOrder ) );
_Ay( idx_row, unsigned( idx_col ) ) = -0.5 * Sgn( idx_kOrder ) * ETilde( idx_lOrder - 1, std::abs( idx_kOrder ) + 1 );
}
}
j = GlobalIndex( idx_lOrder - 1, -kPlus( idx_kOrder ) );
if( j >= 0 && j < int( _nTotalEntries ) ) {
_Ay( i, unsigned( j ) ) = -0.5 * Sgn( idx_kOrder ) * ETilde( idx_lOrder - 1, std::abs( idx_kOrder ) + 1 );
}
j = GlobalIndex( idx_lOrder + 1, -kPlus( idx_kOrder ) );
if( j >= 0 && j < int( _nTotalEntries ) ) {
_Ay( i, unsigned( j ) ) = 0.5 * Sgn( idx_kOrder ) * FTilde( idx_lOrder + 1, std::abs( idx_kOrder ) + 1 );
if( CheckIndex( idx_lOrder + 1, -kPlus( idx_kOrder ) ) ) {
idx_col = GlobalIndex( idx_lOrder + 1, -kPlus( idx_kOrder ) );
_Ay( idx_row, unsigned( idx_col ) ) = 0.5 * Sgn( idx_kOrder ) * FTilde( idx_lOrder + 1, std::abs( idx_kOrder ) + 1 );
}
}
//
// flux matrix in direction z
j = GlobalIndex( idx_lOrder - 1, idx_kOrder );
if( j >= 0 && j < int( _nTotalEntries ) ) {
_Az( i, unsigned( j ) ) = AParam( idx_lOrder - 1, idx_kOrder );
}
{
if( CheckIndex( idx_lOrder - 1, idx_kOrder ) ) {
idx_col = GlobalIndex( idx_lOrder - 1, idx_kOrder );
_Az( idx_row, unsigned( idx_col ) ) = AParam( idx_lOrder - 1, idx_kOrder );
}
j = GlobalIndex( idx_lOrder + 1, idx_kOrder );
if( j >= 0 && j < int( _nTotalEntries ) ) {
_Az( i, unsigned( j ) ) = BParam( idx_lOrder + 1, idx_kOrder );
if( CheckIndex( idx_lOrder + 1, idx_kOrder ) ) {
idx_col = GlobalIndex( idx_lOrder + 1, idx_kOrder );
_Az( idx_row, unsigned( idx_col ) ) = BParam( idx_lOrder + 1, idx_kOrder );
}
}
}
}
}
void PNSolver::ComputeFluxComponents() {
Vector eigenValues( _nTotalEntries );
Vector eigenValues( _nTotalEntries, 0 );
Vector eigenValuesX( _nTotalEntries, 0 );
Vector eigenValuesY( _nTotalEntries, 0 );
MatrixCol eigenVectors( _nTotalEntries, _nTotalEntries, 0 ); // ColumnMatrix for _AxPlus * eigenVectors Multiplication via SIMD
// --- For x Direction ---
{
......@@ -192,17 +223,23 @@ void PNSolver::ComputeFluxComponents() {
for( unsigned idx_ij = 0; idx_ij < _nTotalEntries; idx_ij++ ) {
if( eigenValues[idx_ij] >= 0 ) {
_AxPlus( idx_ij, idx_ij ) = eigenValues[idx_ij]; // positive part of Diagonal Matrix stored in _AxPlus
_AxAbs( idx_ij, idx_ij ) = eigenValues[idx_ij];
}
else {
_AxMinus( idx_ij, idx_ij ) = eigenValues[idx_ij]; // negative part of Diagonal Matrix stored in _AxMinus
_AxAbs( idx_ij, idx_ij ) = -eigenValues[idx_ij];
}
}
_AxPlus = eigenVectors * _AxPlus; // col*row minimum performance
_AxMinus = eigenVectors * _AxMinus;
_AxAbs = eigenVectors * _AxAbs;
blaze::transpose( eigenVectors );
_AxPlus = _AxPlus * eigenVectors; // row*col maximum performance
_AxMinus = _AxMinus * eigenVectors;
_AxAbs = _AxAbs * eigenVectors;
eigenValuesX = eigenValues;
}
// --- For y Direction -------
{
......@@ -212,17 +249,23 @@ void PNSolver::ComputeFluxComponents() {
for( unsigned idx_ij = 0; idx_ij < _nTotalEntries; idx_ij++ ) {
if( eigenValues[idx_ij] >= 0 ) {
_AyPlus( idx_ij, idx_ij ) = eigenValues[idx_ij]; // positive part of Diagonal Matrix stored in _AxPlus
_AyAbs( idx_ij, idx_ij ) = eigenValues[idx_ij];
}
else {
_AyMinus( idx_ij, idx_ij ) = eigenValues[idx_ij]; // negative part of Diagonal Matrix stored in _AxMinus
_AyAbs( idx_ij, idx_ij ) = -eigenValues[idx_ij];
}
}
_AyPlus = eigenVectors * _AyPlus;
_AyMinus = eigenVectors * _AyMinus;
_AyAbs = eigenVectors * _AyAbs;
blaze::transpose( eigenVectors );
_AyPlus = _AyPlus * eigenVectors;
_AyMinus = _AyMinus * eigenVectors;
_AyAbs = _AyAbs * eigenVectors;
eigenValuesY = eigenValues;
}
// --- For z Direction -------
{
......@@ -232,18 +275,33 @@ void PNSolver::ComputeFluxComponents() {
for( unsigned idx_ij = 0; idx_ij < _nTotalEntries; idx_ij++ ) {
if( eigenValues[idx_ij] >= 0 ) {
_AzPlus( idx_ij, idx_ij ) = eigenValues[idx_ij]; // positive part of Diagonal Matrix stored in _AxPlus
_AzAbs( idx_ij, idx_ij ) = eigenValues[idx_ij];
}
else {
_AzMinus( idx_ij, idx_ij ) = eigenValues[idx_ij]; // negative part of Diagonal Matrix stored in _AxMinus
_AzAbs( idx_ij, idx_ij ) = -eigenValues[idx_ij];
}
}
_AzPlus = eigenVectors * _AzPlus;
_AzMinus = eigenVectors * _AzMinus;
_AzAbs = eigenVectors * _AzAbs;
blaze::transpose( eigenVectors );
_AzPlus = _AzPlus * eigenVectors;
_AzMinus = _AzMinus * eigenVectors;
_AzAbs = _AzAbs * eigenVectors;
}
// Compute Spectral Radius
std::cout << "Eigenvalues x direction " << eigenValuesX << "\n";
std::cout << "Eigenvalues y direction " << eigenValuesY << "\n";
std::cout << "Eigenvalues z direction " << eigenValues << "\n";
std::cout << "Spectral Radius X " << blaze::max( blaze::abs( eigenValuesX ) ) << "\n";
std::cout << "Spectral Radius Y " << blaze::max( blaze::abs( eigenValuesY ) ) << "\n";
std::cout << "Spectral Radius Z " << blaze::max( blaze::abs( eigenValues ) ) << "\n";
std::cout << "Spectral Radius combined " << blaze::max( blaze::abs( eigenValues + eigenValuesX + eigenValuesY ) ) << "\n";
}
void PNSolver::ComputeScatterMatrix() {
......@@ -256,7 +314,7 @@ void PNSolver::ComputeScatterMatrix() {
// Only isotropic scattering: k = 1/(2pi) in 2d !!!
unsigned nSteps = 50;
unsigned nSteps = 500000;
double integralSum = 0;
unsigned idx_global = 0;
......@@ -308,6 +366,14 @@ void PNSolver::Solve() {
Vector fluxNew( _nCells, 0.0 );
Vector fluxOld( _nCells, 0.0 );
for( unsigned i = 0; i < _nCells; ++i ) {
_solverOutput[i] = _psi[i][0];
}
Save( -1 ); // Save initial condition
VectorVector cellMids = _mesh->GetCellMidPoints();
int rank;
unsigned idx_system = 0;
......@@ -316,6 +382,7 @@ void PNSolver::Solve() {
if( rank == 0 ) log->info( "{:10} {:10}", "t", "dFlux" );
// Loop over energies (pseudo-time of continuous slowing down approach)
for( unsigned idx_energy = 0; idx_energy < _nEnergies; idx_energy++ ) {
// Loop over all spatial cells
......@@ -323,87 +390,106 @@ void PNSolver::Solve() {
if( _boundaryCells[idx_cell] == BOUNDARY_TYPE::DIRICHLET ) continue; // Dirichlet cells stay at IC, farfield assumption
// Reset temporary variable psiNew
for( int idx_lOrder = 0; idx_lOrder < int( _nq ); idx_lOrder++ ) {
for( int idx_kOrder = -idx_lOrder; idx_kOrder < idx_lOrder; idx_kOrder++ ) {
for( int idx_lOrder = 0; idx_lOrder <= int( _nq ); idx_lOrder++ ) {
for( int idx_kOrder = -idx_lOrder; idx_kOrder <= idx_lOrder; idx_kOrder++ ) {
idx_system = unsigned( GlobalIndex( idx_lOrder, idx_kOrder ) );
psiNew[idx_cell][idx_system] = 0.0;
}
}
if( _mesh->GetDistanceToOrigin( idx_cell ) <= 0.1 ) {
// std::cout << "Distance to origin: " << _mesh->GetDistanceToOrigin( idx_cell ) << "\n";
// std::cout << "Old Cell value: \n " << _psi[idx_cell] << "\n" << psiNew[idx_cell] << "\n";
}
// Loop over all neighbor cells (edges) of cell j and compute numerical fluxes
for( unsigned idx_neighbor = 0; idx_neighbor < _neighbors[idx_cell].size(); idx_neighbor++ ) {
// Compute flux contribution and store in psiNew to save memory
if( _boundaryCells[idx_cell] == BOUNDARY_TYPE::NEUMANN && _neighbors[idx_cell][idx_neighbor] == _nCells )
_g->Flux( _AxPlus,
_AxMinus,
_AyPlus,
_AyMinus,
_AzPlus,
_AzMinus,
_psi[idx_cell],
_psi[idx_cell],
_normals[idx_cell][idx_neighbor],
psiNew[idx_cell] );
_g->FluxVanLeer(
_Ax, _AxAbs, _Ay, _AyAbs, _Az, _AzAbs, _psi[idx_cell], _psi[idx_cell], _normals[idx_cell][idx_neighbor], psiNew[idx_cell] );
// _g->Flux( _AxPlus,
// _AxMinus,
// _AyPlus,
// _AyMinus,
// _AzPlus,
// _AzMinus,
// _psi[idx_cell],
// _psi[idx_cell],
// _normals[idx_cell][idx_neighbor],
// psiNew[idx_cell] );
else
_g->Flux( _AxPlus,
_AxMinus,
_AyPlus,
_AyMinus,
_AzPlus,
_AzMinus,
_psi[idx_cell],
_psi[_neighbors[idx_cell][idx_neighbor]],
_normals[idx_cell][idx_neighbor],
psiNew[idx_cell] );
_g->FluxVanLeer( _Ax,
_AxAbs,
_Ay,
_AyAbs,
_Az,
_AzAbs,
_psi[idx_cell],
_psi[_neighbors[idx_cell][idx_neighbor]],
_normals[idx_cell][idx_neighbor],
psiNew[idx_cell] );
//_g->Flux( _AxPlus,
// _AxMinus,
// _AyPlus,
// _AyMinus,
// _AzPlus,
// _AzMinus,
// _psi[idx_cell],
// _psi[_neighbors[idx_cell][idx_neighbor]],
// _normals[idx_cell][idx_neighbor],
// psiNew[idx_cell] );
// if( _mesh->GetDistanceToOrigin( idx_cell ) <= 0.1 ) std::cout << "FluxPart " << idx_neighbor << " : \n" << psiNew[idx_cell] <<
// "\n";
}
// time update angular flux with numerical flux and total scattering cross section
for( int idx_lOrder = 0; idx_lOrder < int( _nq ); idx_lOrder++ ) {
for( int idx_kOrder = -idx_lOrder; idx_kOrder < idx_lOrder; idx_kOrder++ ) {
for( int idx_lOrder = 0; idx_lOrder <= int( _nq ); idx_lOrder++ ) {
for( int idx_kOrder = -idx_lOrder; idx_kOrder <= idx_lOrder; idx_kOrder++ ) {
idx_system = unsigned( GlobalIndex( idx_lOrder, idx_kOrder ) );
psiNew[idx_cell][idx_system] = _psi[idx_cell][idx_system] /* value at last time */
- ( _dE / _areas[idx_cell] ) * psiNew[idx_cell][idx_system] /* cell averaged flux */
psiNew[idx_cell][idx_system] = _psi[idx_cell][idx_system] -
( _dE / _areas[idx_cell] ) * psiNew[idx_cell][idx_system] /* cell averaged flux */
- _dE * _psi[idx_cell][idx_system] *
( _sigmaA[idx_energy][idx_cell] /* absorbtion influence */
+ _sigmaS[idx_energy][idx_cell] * _scatterMatDiag[idx_system] ); /* scattering influence */
}
}
// TODO: Add Source Term!!! (not neccessary in LineSource
// TODO: figure out a more elegant way
// add external source contribution
// if( _Q.size() == 1u ) { // constant source for all energies
// if( _Q[0][idx_cell].size() == 1u ) // isotropic source
// psiNew[idx_cell] += _dE * _Q[0][idx_cell][0];
// else
// psiNew[idx_cell] += _dE * _Q[0][idx_cell];
//}
// else {
// if( _Q[0][idx_cell].size() == 1u ) // isotropic source
// psiNew[idx_cell] += _dE * _Q[idx_energy][idx_cell][0];
// else
// psiNew[idx_cell] += _dE * _Q[idx_energy][idx_cell];
//}
}
_psi = psiNew;
double mass = 0.0;
for( unsigned i = 0; i < _nCells; ++i ) {
fluxNew[i] = _psi[i][