Commit 5f944061 authored by steffen.schotthoefer's avatar steffen.schotthoefer
Browse files

restructuring of MN_Solver, still wrong flux

parent 94ff144a
Pipeline #95818 failed with stages
in 31 minutes and 10 seconds
...@@ -50,11 +50,10 @@ class MNSolver : public Solver ...@@ -50,11 +50,10 @@ class MNSolver : public Solver
*/ */
int GlobalIndex( int l, int k ) const; int GlobalIndex( int l, int k ) const;
/*! @brief : Construct flux by computing the Moment of the FVM discretization at the interface of cell /*! @brief : Construct flux by computing the Moment of the sum of FVM discretization at the interface of cell
* @param : idx_cell = current cell id * @param : idx_cell = current cell id
* @param : idx_neighbor = neighbor cell id * @returns : sum over all neighbors of flux for all moments at interface of idx_cell, idx_neighbor */
* @returns : flux for all moments at interface of idx_cell,idx_neighbor */ Vector ConstructFlux( unsigned idx_cell );
Vector ConstructFlux( unsigned idx_cell, unsigned idx_neighbor );
/*! @brief : Pre-Compute Moments at all quadrature points. */ /*! @brief : Pre-Compute Moments at all quadrature points. */
void ComputeMoments(); void ComputeMoments();
......
...@@ -18,28 +18,28 @@ ...@@ -18,28 +18,28 @@
int main( int argc, char** argv ) { int main( int argc, char** argv ) {
MPI_Init( &argc, &argv ); MPI_Init( &argc, &argv );
QGaussLegendreTensorized quad( 4 ); // QGaussLegendreTensorized quad( 4 );
SphericalHarmonics testBase( 2 ); // SphericalHarmonics testBase( 2 );
//
double x, y, z, w; // double x, y, z, w;
Vector moment = testBase.ComputeSphericalBasis( 0, 1, 0 ); // Vector moment = testBase.ComputeSphericalBasis( 0, 1, 0 );
// 9 basis moments if degree = 2 // // 9 basis moments if degree = 2
//
Vector results( moment.size(), 0.0 ); // Vector results( moment.size(), 0.0 );
//
for( unsigned idx_quad = 0; idx_quad < quad.GetNq(); idx_quad++ ) { // for( unsigned idx_quad = 0; idx_quad < quad.GetNq(); idx_quad++ ) {
x = quad.GetPoints()[idx_quad][0]; // x = quad.GetPoints()[idx_quad][0];
y = quad.GetPoints()[idx_quad][1]; // y = quad.GetPoints()[idx_quad][1];
z = quad.GetPoints()[idx_quad][2]; // z = quad.GetPoints()[idx_quad][2];
w = quad.GetWeights()[idx_quad]; // w = quad.GetWeights()[idx_quad];
moment = testBase.ComputeSphericalBasis( x, y, z ); // moment = testBase.ComputeSphericalBasis( x, y, z );
//
for( unsigned idx_sys = 0; idx_sys < 9; idx_sys++ ) { // for( unsigned idx_sys = 0; idx_sys < 9; idx_sys++ ) {
results[idx_sys] += w * moment[idx_sys]; // results[idx_sys] += w * moment[idx_sys];
// std::cout << idx_quad << ": " << results[0] << "\n"; // // std::cout << idx_quad << ": " << results[0] << "\n";
} // }
} //}
std::cout << "moment integration:\n " << results << "\n"; // std::cout << "moment integration:\n " << results << "\n";
// //
// // Normalized integration // // Normalized integration
// Vector resultsNormal( moment.size(), 0.0 ); // Vector resultsNormal( moment.size(), 0.0 );
......
...@@ -72,18 +72,18 @@ VectorVector LineSource_PN::SetupIC() { ...@@ -72,18 +72,18 @@ VectorVector LineSource_PN::SetupIC() {
VectorVector cellMids = _mesh->GetCellMidPoints(); VectorVector cellMids = _mesh->GetCellMidPoints();
// Initial condition is dirac impulse at (x,y) = (0,0) ==> constant in angle ==> all moments are zero. // Initial condition is dirac impulse at (x,y) = (0,0) ==> constant in angle ==> all moments are zero.
double t = 3.2e-4; // pseudo time for gaussian smoothing (Approx to dirac impulse) // double t = 3.2e-4; // pseudo time for gaussian smoothing (Approx to dirac impulse)
for( unsigned j = 0; j < cellMids.size(); ++j ) {
double x = cellMids[j][0];
double y = cellMids[j][1];
psi[j][0] = 1.0 / ( 4.0 * M_PI * t ) * std::exp( -( x * x + y * y ) / ( 4 * t ) );
}
// for( unsigned j = 0; j < cellMids.size(); ++j ) { // for( unsigned j = 0; j < cellMids.size(); ++j ) {
// if( cellMids[j][0] < 0 && cellMids[j][1] > 0 ) // double x = cellMids[j][0];
// psi[j][0] = 1.0; // double y = cellMids[j][1];
// else // psi[j][0] = 1.0 / ( 4.0 * M_PI * t ) * std::exp( -( x * x + y * y ) / ( 4 * t ) );
// psi[j][0] = 0.0;
//} //}
for( unsigned j = 0; j < cellMids.size(); ++j ) {
if( cellMids[j][0] > -0.2 && cellMids[j][1] > -0.2 && cellMids[j][1] < 0.2 && cellMids[j][0] < 0.2 )
psi[j][0] = 1.0;
else
psi[j][0] = 0.0;
}
return psi; return psi;
} }
...@@ -29,14 +29,11 @@ MNSolver::MNSolver( Config* settings ) : Solver( settings ), _nMaxMomentsOrder( ...@@ -29,14 +29,11 @@ MNSolver::MNSolver( Config* settings ) : Solver( settings ), _nMaxMomentsOrder(
// Initialize Optimizer // Initialize Optimizer
_optimizer = OptimizerBase::Create( _settings ); _optimizer = OptimizerBase::Create( _settings );
// Initialize lagrange Multipliers // Initialize lagrange Multiplier
_alpha = VectorVector( _nCells ); _alpha = VectorVector( _nCells, Vector( _nTotalEntries, 0.0 ) );
for( unsigned idx_cells = 0; idx_cells < _nTotalEntries; idx_cells++ ) {
_alpha[idx_cells] = Vector( _nTotalEntries, 0.0 );
}
// Initialize and Pre-Compute Moments at quadrature points // Initialize and Pre-Compute Moments at quadrature points
_moments = VectorVector( _nq ); _moments = VectorVector( _nq, Vector( _nTotalEntries, 0.0 ) );
ComputeMoments(); ComputeMoments();
} }
...@@ -52,35 +49,6 @@ int MNSolver::GlobalIndex( int l, int k ) const { ...@@ -52,35 +49,6 @@ int MNSolver::GlobalIndex( int l, int k ) const {
return numIndicesPrevLevel + prevIndicesThisLevel; return numIndicesPrevLevel + prevIndicesThisLevel;
} }
Vector MNSolver::ConstructFlux( unsigned idx_cell, unsigned idx_neigh ) {
// ---- Integration of Moment of flux ----
double x, y, w, entropy, velocity;
// double z;
Vector flux( _nTotalEntries, 0.0 );
for( unsigned idx_quad = 0; idx_quad < _nq; idx_quad++ ) {
x = _quadrature->GetPoints()[idx_quad][0];
y = _quadrature->GetPoints()[idx_quad][1];
// z = _quadrature->GetPoints()[idx_quad][2];
w = _quadrature->GetWeights()[idx_quad];
// --- get upwinding direction (2D)
// DOUBLE CHECK IF WE NEED DIMENSION SPLITTING!!!
velocity = _normals[idx_cell][idx_neigh][0] * x + _normals[idx_cell][idx_neigh][1] * y;
// Perform upwinding
( velocity > 0 ) ? ( entropy = _entropy->EntropyPrimeDual( blaze::dot( _alpha[idx_cell], _moments[idx_quad] ) ) )
: ( entropy = _entropy->EntropyPrimeDual( blaze::dot( _alpha[idx_neigh], _moments[idx_quad] ) ) );
// integrate
flux += _moments[idx_quad] * ( w * velocity * entropy );
}
return flux;
}
void MNSolver::ComputeMoments() { void MNSolver::ComputeMoments() {
double x, y, z, w; double x, y, z, w;
...@@ -91,7 +59,7 @@ void MNSolver::ComputeMoments() { ...@@ -91,7 +59,7 @@ void MNSolver::ComputeMoments() {
_moments[idx_quad] = _basis.ComputeSphericalBasis( x, y, z ); _moments[idx_quad] = _basis.ComputeSphericalBasis( x, y, z );
} }
Vector results( _moments[0].size(), 0.0 ); Vector normalizationFactor( _moments[0].size(), 0.0 );
// Normalize Moments // Normalize Moments
...@@ -101,16 +69,67 @@ void MNSolver::ComputeMoments() { ...@@ -101,16 +69,67 @@ void MNSolver::ComputeMoments() {
z = _quadrature->GetPoints()[idx_quad][2]; z = _quadrature->GetPoints()[idx_quad][2];
w = _quadrature->GetWeights()[idx_quad]; w = _quadrature->GetWeights()[idx_quad];
for( unsigned idx_sys = 0; idx_sys < 9; idx_sys++ ) { for( unsigned idx_sys = 0; idx_sys < _nTotalEntries; idx_sys++ ) {
results[idx_sys] += w * _moments[idx_quad][idx_sys] * _moments[idx_quad][idx_sys]; normalizationFactor[idx_sys] += w * _moments[idx_quad][idx_sys] * _moments[idx_quad][idx_sys];
} }
} }
std::cout << "norm" << normalizationFactor << "\n";
for( unsigned idx_quad = 0; idx_quad < _nq; idx_quad++ ) {
for( unsigned idx_sys = 0; idx_sys < _nTotalEntries; idx_sys++ ) {
_moments[idx_quad][idx_sys] /= sqrt( normalizationFactor[idx_sys] );
}
}
}
Vector MNSolver::ConstructFlux( unsigned idx_cell ) {
// ---- Integration of Moment of flux ----
double w, entropyL, entropyR, entropyFlux;
// double x, y, z;
// std::cout << "--------\n";
// std::cout << " alphas curr cell" << _alpha[idx_cell] << " alphas neigh cell:\n";
bool good = _alpha[idx_cell] == 0.0;
int idx_good = 0;
for( unsigned idx_neigh = 0; idx_neigh < _neighbors[idx_cell].size(); idx_neigh++ ) {
// std::cout << _alpha[idx_neigh] << "\n";
if( _alpha[idx_neigh] == 0.0 ) idx_good++;
}
if( idx_good == 2 && good ) {
std::cout << "Candidate\n";
}
Vector flux( _nTotalEntries, 0.0 );
for( unsigned idx_quad = 0; idx_quad < _nq; idx_quad++ ) { for( unsigned idx_quad = 0; idx_quad < _nq; idx_quad++ ) {
for( unsigned idx_sys = 0; idx_sys < 9; idx_sys++ ) {
_moments[idx_quad][idx_sys] /= sqrt( results[idx_sys] ); w = _quadrature->GetWeights()[idx_quad];
entropyFlux = 0.0; // Reset temorary flux
entropyL = dot( _alpha[idx_cell], _moments[idx_quad] );
// _entropy->EntropyPrimeDual( blaze::dot( _alpha[idx_cell], _moments[idx_quad] ) );
for( unsigned idx_neigh = 0; idx_neigh < _neighbors[idx_cell].size(); idx_neigh++ ) {
// Store fluxes in psiNew, to save memory
if( _boundaryCells[idx_cell] == BOUNDARY_TYPE::NEUMANN && _neighbors[idx_cell][idx_neigh] == _nCells )
entropyR = entropyL;
else {
entropyR = dot( _alpha[idx_neigh], _moments[idx_quad] );
//_entropy->EntropyPrimeDual( blaze::dot( _alpha[idx_neigh], _moments[idx_quad] ) );
}
entropyFlux += _g->Flux( _quadrature->GetPoints()[idx_quad], entropyL, entropyR, _normals[idx_cell][idx_neigh] );
} }
// std::cout << "\n entropy Flux at cell [" << idx_cell << "] and quad [" << idx_quad << "]: " << entropyFlux << "\n";
// integrate
flux += _moments[idx_quad] * ( w * entropyFlux );
} }
// std::cout << "\n integrate entropy Flux at cell [" << idx_cell << "] and : " << flux << "\n";
return flux;
} }
void MNSolver::Solve() { void MNSolver::Solve() {
...@@ -132,6 +151,11 @@ void MNSolver::Solve() { ...@@ -132,6 +151,11 @@ void MNSolver::Solve() {
mass1 += _psi[i][0] * _areas[i]; mass1 += _psi[i][0] * _areas[i];
} }
dFlux = blaze::l2Norm( fluxNew - fluxOld );
fluxOld = fluxNew;
Save( -1 );
if( rank == 0 ) log->info( "{:10} {:10}", "t", "dFlux" ); if( rank == 0 ) log->info( "{:10} {:10}", "t", "dFlux" );
if( rank == 0 ) log->info( "{:03.8f} {:01.5e} {:01.5e}", -1.0, dFlux, mass1 ); if( rank == 0 ) log->info( "{:03.8f} {:01.5e} {:01.5e}", -1.0, dFlux, mass1 );
...@@ -146,25 +170,16 @@ void MNSolver::Solve() { ...@@ -146,25 +170,16 @@ void MNSolver::Solve() {
// Loop over the grid cells // Loop over the grid cells
for( unsigned idx_cell = 0; idx_cell < _nCells; idx_cell++ ) { for( unsigned idx_cell = 0; idx_cell < _nCells; idx_cell++ ) {
// Reset temporary variable
for( unsigned idx_sys = 0; idx_sys < _nTotalEntries; idx_sys++ ) {
psiNew[idx_cell][idx_sys] = 0.0;
}
// ------- Reconstruction Step ------- // ------- Reconstruction Step -------
_alpha[idx_cell] = _optimizer->Solve( _psi[idx_cell] ); _alpha[idx_cell] = _psi[idx_cell]; // _optimizer->Solve( _psi[idx_cell] );
// ------- Flux Computation Step --------- // ------- Flux Computation Step ---------
// Loop over neighbors // Dirichlet Boundaries are finished now
for( unsigned idx_neigh = 0; idx_neigh < _neighbors[idx_cell].size(); idx_neigh++ ) { if( _boundaryCells[idx_cell] == BOUNDARY_TYPE::DIRICHLET ) continue;
// Store fluxes in psiNew, to save memory
psiNew[idx_cell] += ConstructFlux( idx_cell, idx_neigh );
// std::cout << " psiNew[" << idx_cell << "] " << psiNew[idx_cell] << "\n";
}
// std::cout << " TOTAL psiNew[" << idx_cell << "] " << psiNew[idx_cell] << "\n"; psiNew[idx_cell] = ConstructFlux( idx_cell );
// ------ FVM Step ------ // ------ FVM Step ------
...@@ -189,10 +204,10 @@ void MNSolver::Solve() { ...@@ -189,10 +204,10 @@ void MNSolver::Solve() {
mass += _psi[idx_cell][0] * _areas[idx_cell]; mass += _psi[idx_cell][0] * _areas[idx_cell];
} }
Save( idx_energy );
dFlux = blaze::l2Norm( fluxNew - fluxOld ); dFlux = blaze::l2Norm( fluxNew - fluxOld );
fluxOld = fluxNew; fluxOld = fluxNew;
if( rank == 0 ) log->info( "{:03.8f} {:01.5e} {:01.5e}", _energies[idx_energy], dFlux, mass ); if( rank == 0 ) log->info( "{:03.8f} {:01.5e} {:01.5e}", _energies[idx_energy], dFlux, mass );
Save( idx_energy );
} }
} }
......
...@@ -69,6 +69,10 @@ PNSolver::PNSolver( Config* settings ) : Solver( settings ) { ...@@ -69,6 +69,10 @@ PNSolver::PNSolver( Config* settings ) : Solver( settings ) {
} }
void PNSolver::Solve() { void PNSolver::Solve() {
int rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
auto log = spdlog::get( "event" ); auto log = spdlog::get( "event" );
// angular flux at next time step (maybe store angular flux at all time steps, since time becomes energy?) // angular flux at next time step (maybe store angular flux at all time steps, since time becomes energy?)
...@@ -88,13 +92,9 @@ void PNSolver::Solve() { ...@@ -88,13 +92,9 @@ void PNSolver::Solve() {
Save( -1 ); // Save initial condition Save( -1 ); // Save initial condition
int rank;
unsigned idx_system = 0; unsigned idx_system = 0;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
if( rank == 0 ) log->info( "{:10} {:10}", "t", "dFlux" ); if( rank == 0 ) log->info( "{:10} {:10}", "t", "dFlux" );
if( rank == 0 ) log->info( "{:03.8f} {:01.5e} {:01.5e}", -1.0, dFlux, mass1 ); if( rank == 0 ) log->info( "{:03.8f} {:01.5e} {:01.5e}", -1.0, dFlux, mass1 );
// Loop over energies (pseudo-time of continuous slowing down approach) // Loop over energies (pseudo-time of continuous slowing down approach)
...@@ -156,7 +156,6 @@ void PNSolver::Solve() { ...@@ -156,7 +156,6 @@ void PNSolver::Solve() {
dFlux = blaze::l2Norm( fluxNew - fluxOld ); dFlux = blaze::l2Norm( fluxNew - fluxOld );
fluxOld = fluxNew; fluxOld = fluxNew;
if( rank == 0 ) { if( rank == 0 ) {
// std::cout << "PseudoTime: " << _energies[idx_energy] << " | Flux Change: " << dFlux << " | Mass: " << mass << "\n";
log->info( "{:03.8f} {:01.5e} {:01.5e}", _energies[idx_energy], dFlux, mass ); log->info( "{:03.8f} {:01.5e} {:01.5e}", _energies[idx_energy], dFlux, mass );
} }
Save( idx_energy ); Save( idx_energy );
......
...@@ -27,10 +27,11 @@ Vector SphericalHarmonics::ComputeSphericalBasis( double x, double y, double z ) ...@@ -27,10 +27,11 @@ Vector SphericalHarmonics::ComputeSphericalBasis( double x, double y, double z )
// transform (x,y,z) into (my,phi) // transform (x,y,z) into (my,phi)
double my = z; double my = z;
double phi = 0.0; double phi = 0.0;
if( y >= 0 ) if( y >= 0 )
phi = acos( x ); phi = acos( x );
else else
phi = acos( -x ) + M_PI; phi = 2 * M_PI - acos( x );
ComputeAssLegendrePoly( my ); ComputeAssLegendrePoly( my );
ComputeYBasis( phi ); ComputeYBasis( phi );
......
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